arch/: Make sure the up_irq_enable() is available on all architectures. I will not be able to test all of these new versions of this function so this may break things for awhile.

This commit is contained in:
Gregory Nutt 2018-06-06 09:25:40 -06:00
parent f88a4c6ea8
commit 9222f50e1c
24 changed files with 316 additions and 118 deletions

View File

@ -118,19 +118,19 @@
/* This struct defines the way the registers are stored. We
* need to save:
*
* 1 CPSR
* 7 Static registers, v1-v7 (aka r4-r10)
* 1 Frame pointer, fp (aka r11)
* 1 Stack pointer, sp (aka r13)
* 1 Return address, lr (aka r14)
* 1 CPSR
* 7 Static registers, v1-v7 (aka r4-r10)
* 1 Frame pointer, fp (aka r11)
* 1 Stack pointer, sp (aka r13)
* 1 Return address, lr (aka r14)
* ---
* 11 (XCPTCONTEXT_USER_REG)
* 11 (XCPTCONTEXT_USER_REG)
*
* On interrupts, we also need to save:
* 4 Volatile registers, a1-a4 (aka r0-r3)
* 1 Scratch Register, ip (aka r12)
*---
* 5 (XCPTCONTEXT_IRQ_REGS)
* 4 Volatile registers, a1-a4 (aka r0-r3)
* 1 Scratch Register, ip (aka r12)
* ---
* 5 (XCPTCONTEXT_IRQ_REGS)
*
* For a total of 17 (XCPTCONTEXT_REGS)
*/
@ -212,6 +212,23 @@ static inline void up_irq_restore(irqstate_t flags)
: "r" (flags)
: "memory");
}
/* Enable IRQs and return the previous IRQ state */
static inline irqstate_t up_irq_enable(void)
{
unsigned int flags;
unsigned int temp;
__asm__ __volatile__
(
"\tmrs %0, cpsr\n"
"\tbic %1, %0, #128\n"
"\tmsr cpsr_c, %1"
: "=r" (flags), "=r" (temp)
:
: "memory");
return flags;
}
#endif /* __ASSEMBLY__ */
/****************************************************************************

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/include/armv7-a/irq.h
*
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2013-2014, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/avr/include/avr32/irq.h
*
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
* Copyright (C) 2010, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -167,7 +167,7 @@ static inline uint32_t avr32_evba(void)
return evba;
}
/* Save the current interrupt enable state & disable all interrupts */
/* Return the current interrupt enable state and disable all interrupts */
static inline irqstate_t up_irq_save(void)
{
@ -185,7 +185,7 @@ static inline irqstate_t up_irq_save(void)
/* Restore saved interrupt state */
static inline void up_irq_restore(irqstate_t flags)
{
{
if ((flags & AVR32_SR_GM_MASK) == 0)
{
__asm__ __volatile__ (
@ -198,6 +198,21 @@ static inline void up_irq_restore(irqstate_t flags)
}
}
/* Return the current interrupt enable state and enable all interrupts */
static inline irqstate_t up_irq_enable(void)
{
irqstate_t sr = (irqstate_t)avr32_sr();
__asm__ __volatile__ (
"csrf\t%0\n\t"
"nop\n\t"
"nop"
:
: "i" (AVR32_SR_GM_SHIFT)
);
return sr;
}
#endif /* __ASSEMBLY__ */
/****************************************************************************

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/mips/include/mips32/irq.h
*
* Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2013, 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -557,6 +557,22 @@ irqstate_t up_irq_save(void);
void up_irq_restore(irqstate_t irqtate);
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Enable interrupts
*
* Input Parameters:
* None.
*
* Returned Value:
* None
*
****************************************************************************/
void up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -50,18 +50,6 @@
#include "up_internal.h"
#include "up_arch.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/mips/src/mips32/up_irq.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -78,7 +78,7 @@ irqstate_t up_irq_save(void)
* Name: up_irq_restore
*
* Description:
* Restore the previous interrutp state (i.e., the one previously returned
* Restore the previous up_irq_enable state (i.e., the one previously returned
* by up_irq_save())
*
* Input Parameters:
@ -100,3 +100,38 @@ void up_irq_restore(irqstate_t irqstate)
status |= CP0_STATUS_IM_SWINTS; /* Make sure that S/W interrupts enabled */
cp0_putstatus(status); /* Restore interrupt state */
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Enable interrupts
*
* Input Parameters:
* None.
*
* Returned Value:
* None
*
****************************************************************************/
void up_irq_enable(void)
{
register irqstate_t status;
/* Set the status register. It will be the same as the current status
* register with some changes:
*
* 1. Clear the BEV bit (This bit should already be clear)
* 2. Clear the UM bit so that the task executes in kernel mode
* (This bit should already be clear)
* 3. Make sure the IE is set
* 4. Make sure the S/W interrupts are enabled
* 5. Set the interrupt mask bits
*/
status = cp0_getstatus();
status &= ~(CP0_STATUS_BEV | CP0_STATUS_UM);
status |= (CP0_STATUS_IE | CP0_STATUS_IM_SWINTS | CP0_STATUS_IM_ALL);
cp0_putstatus(status);
}

View File

@ -70,6 +70,7 @@ extern "C"
irqstate_t up_irq_save(void);
void up_irq_restore(irqstate_t flags);
irqstate_t up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -82,6 +82,7 @@ void lm32_irq_initialize(void)
* Name: up_irq_save
*
* Description:
* Return the current interrupt enable state and disable all interrupts.
*
****************************************************************************/
@ -103,6 +104,7 @@ irqstate_t up_irq_save(void)
* Name: up_irq_restore
*
* Description:
* Restore saved interrupt state
*
****************************************************************************/
@ -113,6 +115,28 @@ void up_irq_restore(irqstate_t flags)
irq_setie(flags);
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Return the current interrupt enable state and enable all interrupts
*
****************************************************************************/
irqstate_t up_irq_restore(irqstate_t flags)
{
irqstate_t flags;
/* Get the previous value of IE */
flags = irq_getie();
/* Enable interrupts and return the previous interrupt state */
irq_setie(1);
return flags;
}
/****************************************************************************
* Name: up_disable_irq
*

View File

@ -1,7 +1,7 @@
/************************************************************************************
* arch/renesas/include/m16c/irq.h
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -289,33 +289,48 @@ extern "C"
* leave_critical section(), are probably what you really want.
*/
/* Save the current interrupt enable state & disable IRQs */
/* Return the current interrupt enable state and disable IRQs */
static inline irqstate_t up_irq_save(void)
{
irqstate_t flags;
__asm__ __volatile__
(
"\tstc flg, %0\n"
"\tfclr I\n"
"\tstc flg, %0\n"
"\tfclr I\n"
: "=r" (flags)
:
: "memory");
return flags;
}
/* Restore saved IRQ & FIQ state */
/* Restore saved IRQ state */
static inline void up_irq_restore(irqstate_t flags)
{
__asm__ __volatile__
(
"ldc %0, flg"
"ldc %0, flg"
:
: "r" (flags)
: "memory");
}
/* Return the current interrupt enable state and enable IRQs */
static inline irqstate_t up_irq_enable(void)
{
irqstate_t flags;
__asm__ __volatile__
(
"\tstc flg, %0\n"
"\tfset I\n"
: "=r" (flags)
:
: "memory");
return flags;
}
#endif
/************************************************************************************

View File

@ -514,7 +514,7 @@ static inline void __setsr(irqstate_t sr)
__asm__ __volatile__ ("ldc %0, sr" : : "r" (sr));
}
/* Return the current interrupt enable state & disable IRQs */
/* Return the current interrupt enable state and disable interrupts */
static inline irqstate_t up_irq_save(void)
{
@ -523,14 +523,15 @@ static inline irqstate_t up_irq_save(void)
return flags;
}
/* Disable IRQs */
/* Disable interrupts */
static inline void up_irq_disable(void)
{
uint32_t flags = __getsr();
__setsr(flags | 0x000000f0);
}
/* Enable IRQs */
/* Enable interrupts */
static inline void up_irq_enable(void)
{
@ -538,7 +539,7 @@ static inline void up_irq_enable(void)
__setsr(flags & ~0x000000f0);
}
/* Restore saved IRQ state */
/* Restore saved interrupt state */
static inline void up_irq_restore(irqstate_t flags)
{

View File

@ -48,18 +48,6 @@
#include "up_internal.h"
#include "up_arch.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -66,6 +66,7 @@
irqstate_t up_irq_save(void);
void up_irq_restore(irqstate_t irqstate);
irqstate_t up_irq_enable(void);
#endif /* __ARCH_RISCV_INCLUDE_NR5M100_IRQ_H */

View File

@ -344,4 +344,3 @@ struct xcptcontext
****************************************************************************/
#endif /* __ARCH_RISCV_INCLUDE_RV32IM_IRQ_H */

View File

@ -204,7 +204,6 @@ void up_irqinitialize(void)
/* Now enable Global Interrupts */
__asm__ volatile("csrrs a0, %0, 3" :: "i"(NR5_EPIC_PRIMASK));
}
/****************************************************************************
@ -283,31 +282,31 @@ int up_prioritize_irq(int irq, int priority)
#endif
/****************************************************************************
* Name: irqsave
* Name: up_irq_save
*
* Description:
* Disable IRQs while returning the previous IRQ state
* Return the current interrupt state and disable interrupts
*
****************************************************************************/
irqstate_t up_irq_save(void)
{
irqstate_t newIrqPri = (2 << 2) | 3;
irqstate_t oldIrqPri;
irqstate_t newpri = (2 << 2) | 3;
irqstate_t oldpri;
/* Set the new IRQ Priority level to level 2, enabled.
* This will allow SW and DEBUG / TRAP interrupts to
* continue to fire, but no general purpose ints.
*/
__asm__ volatile("csrrw %0, %1, %2" : "=r"(oldIrqPri) :
"i"(NR5_EPIC_PRIMASK), "r"(newIrqPri));
__asm__ volatile("csrrw %0, %1, %2" : "=r"(oldpri) :
"i"(NR5_EPIC_PRIMASK), "r"(newpri));
return oldIrqPri;
return oldpri;
}
/****************************************************************************
* Name: irqrestore
* Name: up_irq_restore
*
* Description:
* Restore previous IRQ mask state
@ -318,3 +317,26 @@ void up_irq_restore(irqstate_t pri)
{
__asm__ volatile("csrw %0, %1" :: "i"(NR5_EPIC_PRIMASK), "r"(pri));
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Return the current interrupt state and enable interrupts
*
****************************************************************************/
irqstate_t up_irq_enable(void)
{
irqstate_t newpri = up_get_newintctx();
irqstate_t oldpri;
/* Set the new IRQ Priority level to level 5, enabled. This will allow
* all interrupt.
*/
__asm__ volatile("csrrw %0, %1, %2" : "=r"(oldpri) :
"i"(NR5_EPIC_PRIMASK), "r"(newpri));
return oldpri;
}

View File

@ -49,18 +49,6 @@
#include "up_internal.h"
#include "up_arch.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z16/include/z16f/irq.h
*
* Copyright (C) 2008, 2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2008, 2012, 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -198,6 +198,7 @@ struct xcptcontext
*
* irqstate_t up_irq_save(void);
* void up_irq_restore(irqstate_t flags);
* void up_irq_enable(void);
*
* NOTE: These functions should never be called from application code and,
* as a general rule unless you really know what you are doing, this
@ -209,6 +210,7 @@ struct xcptcontext
#ifdef __ZILOG__
# define up_irq_save() TDI()
# define up_irq_restore(f) RI(f)
# define up_irq_enable() EI()
#endif
/****************************************************************************

View File

@ -251,7 +251,7 @@ extern "C"
/* Name: up_irq_save, up_irq_restore, and friends.
*
* NOTE: This function should never be called from application code and,
* NOTE: These functions should never be called from application code and,
* as a general rule unless you really know what you are doing, this
* function should not be called directly from operation system code either:
* Typically, the wrapper functions, enter_critical_section() and
@ -259,7 +259,8 @@ extern "C"
*/
irqstate_t up_irq_save(void);
void up_irq_restore(irqstate_t flags);
void up_irq_restore(irqstate_t flags);
irqstate_t up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/include/z180/irq.h
*
* Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2012, 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -233,6 +233,7 @@ extern "C"
irqstate_t up_irq_save(void) __naked;
void up_irq_restore(irqstate_t flags) __naked;
irqstate_t up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/include/z8/irq.h
*
* Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -357,7 +357,7 @@ extern "C"
/* Name: up_irq_save, up_irq_restore, and friends.
*
* NOTE: This function should never be called from application code and,
* NOTE: These functions should never be called from application code and,
* as a general rule unless you really know what you are doing, this
* function should not be called directly from operation system code either:
* Typically, the wrapper functions, enter_critical_section() and
@ -365,7 +365,8 @@ extern "C"
*/
irqstate_t up_irq_save(void);
void up_irq_restore(irqstate_t flags);
void up_irq_restore(irqstate_t flags);
irqstate_t up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/include/z80/irq.h
*
* Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -150,6 +150,7 @@ extern "C"
irqstate_t up_irq_save(void) __naked;
void up_irq_restore(irqstate_t flags) __naked;
irqstate_t up_irq_enable(void);
#undef EXTERN
#ifdef __cplusplus

View File

@ -1,7 +1,7 @@
;**************************************************************************
; arch/z80/src/ez80/ez80_irqsave.asm
;
; Copyright (C) 2008 Gregory Nutt. All rights reserved.
; Copyright (C) 2008, 2018 Gregory Nutt. All rights reserved.
; Author: Gregory Nutt <gnutt@nuttx.org>
;
; Redistribution and use in source and binary forms, with or without
@ -60,11 +60,11 @@
;**************************************************************************
_up_irq_save:
ld a, i ; AF = interrupt state
di ; Interrupts are disabled (does not affect F)
push af ; Transfer to HL via the stack
pop hl ;
ret ; And return
ld a, i ; AF = interrupt state
di ; Interrupts are disabled (does not affect F)
push af ; Transfer to HL via the stack
pop hl ;
ret ; And return
;**************************************************************************
;* Name: void up_irq_restore(irqstate_t flags)
@ -75,14 +75,29 @@ _up_irq_save:
;**************************************************************************
_up_irq_restore:
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, _disabled ; Skip over re-enable if Parity odd
ei ; Re-enable interrupts
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, _disabled ; Skip over re-enable if Parity odd
ei ; Re-enable interrupts
_disabled:
push af ; Restore stack
push hl ;
ret ; and return
push af ; Restore stack
push hl ;
ret ; and return
;**************************************************************************
;* Name: irqstate_t up_irq_enable(void)
;*
;* Description:
;* Enable all interrupts; return previous interrupt state
;*
;**************************************************************************
up_irq_enable:
ld a, i ; AF = interrupt state
ei ; Interrupts are enabled (does not affect F)
push af ; Transfer to HL via the stack
pop hl ;
ret ; And return
end

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/src/z180/z180_irq.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -109,11 +109,11 @@ static void z180_seti(uint8_t value) __naked
irqstate_t up_irq_save(void) __naked
{
__asm
ld a, i ; AF Parity bit holds interrupt state
di ; Interrupts are disabled
ld a, i ; AF Parity bit holds interrupt state
di ; Interrupts are disabled
push af ; Return AF in HL
pop hl ;
ret ;
pop hl ;
ret ;
__endasm;
}
@ -128,15 +128,34 @@ irqstate_t up_irq_save(void) __naked
void up_irq_restore(irqstate_t flags) __naked
{
__asm
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, statedisable
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, statedisable
ei
statedisable:
push af ; Restore stack
push hl ;
ret ; and return
ret ; and return
__endasm;
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Enable all interrupts; return previous interrupt state
*
****************************************************************************/
irqstate_t up_irq_enable(void) __naked
{
__asm
ld a, i ; AF Parity bit holds interrupt state
ei ; Interrupts are enabled
push af ; Return AF in HL
pop hl ;
ret ;
__endasm;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/src/z8/z8_irq.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -86,7 +86,8 @@ void up_irqinitialize(void)
* Name: up_irq_save
*
* Description:
* Disable all interrupts; return previous interrupt state
* Disable all interrupts; return previous interrupt state.
* REVISIT: Doen't TDI() do all of this?
*
****************************************************************************/
@ -123,12 +124,39 @@ void up_irq_restore(irqstate_t flags)
if ((flags & 0x80) != 0)
{
/* The IRQE bit was set, re-enable interrupts */
/* The IRQE bit was set, re-enable interrupts.
* REVISIT: Could not RI() so all of this?
*/
EI();
}
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Enable all interrupts; return previous interrupt state
*
****************************************************************************/
irqstate_t up_irq_enable(void)
{
/* Bit 7 (IRQE) of the IRQCTL register determines if interrupts were
* enabled when this function was called.
*/
register irqstate_t retval = getreg8(IRQCTL);
/* Enable interrupts */
EI();
/* Return the previous interrupt state */
return retval;
}
/****************************************************************************
* Name: up_disable_irq
*

View File

@ -1,7 +1,8 @@
/****************************************************************************
* arch/z80/src/z80/z80_irq.c
*
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2012, 2018 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -69,11 +70,11 @@ volatile chipreg_t *g_current_regs;
irqstate_t up_irq_save(void) __naked
{
__asm
ld a, i ; AF Parity bit holds interrupt state
di ; Interrupts are disabled
ld a, i ; AF Parity bit holds interrupt state
di ; Interrupts are disabled
push af ; Return AF in HL
pop hl ;
ret ;
pop hl ;
ret ;
__endasm;
}
@ -88,14 +89,33 @@ irqstate_t up_irq_save(void) __naked
void up_irq_restore(irqstate_t flags) __naked
{
__asm
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, statedisable
di ; Assume disabled
pop hl ; HL = return address
pop af ; AF Parity bit holds interrupt state
jp po, statedisable
ei
statedisable:
push af ; Restore stack
push hl ;
ret ; and return
ret ; and return
__endasm;
}
/****************************************************************************
* Name: up_irq_enable
*
* Description:
* Enable all interrupts; return previous interrupt state
*
****************************************************************************/
irqstate_t up_irq_enable(void) __naked
{
__asm
ld a, i ; AF Parity bit holds interrupt state
ei ; Interrupts are enabled
push af ; Return AF in HL
pop hl ;
ret ;
__endasm;
}