diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/irq_asm.S | 42 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/cpu.c | 14 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/rtems/score/cpu.h | 24 |
3 files changed, 41 insertions, 39 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S index d0550dfad6..ce276cd06a 100644 --- a/c/src/lib/libbsp/sparc/shared/irq_asm.S +++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S @@ -20,7 +20,7 @@ */ #include <rtems/asm.h> -#include <rtems/system.h> +#include <rtems/score/percpu.h> #include <bspopts.h> .macro GET_SELF_CPU_CONTROL REG, TMP @@ -59,19 +59,11 @@ SYM(_CPU_Context_switch): std %g4, [%o0 + G4_OFFSET] std %g6, [%o0 + G6_OFFSET] - ! load the address of the ISR stack nesting prevention flag - sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %g2 - ld [%g2 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %g2 - ! save it a bit later so we do not waste a couple of cycles - std %l0, [%o0 + L0_OFFSET] ! save the local registers std %l2, [%o0 + L2_OFFSET] std %l4, [%o0 + L4_OFFSET] std %l6, [%o0 + L6_OFFSET] - ! Now actually save ISR stack nesting prevention flag - st %g2, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET] - std %i0, [%o0 + I0_OFFSET] ! save the input registers std %i2, [%o0 + I2_OFFSET] std %i4, [%o0 + I4_OFFSET] @@ -82,13 +74,24 @@ SYM(_CPU_Context_switch): std %o4, [%o0 + O4_OFFSET] std %o6, [%o0 + O6_SP_OFFSET] + ! o3 = self per-CPU control + GET_SELF_CPU_CONTROL %o3, %o4 + + ! load the ISR stack nesting prevention flag + ld [%o3 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %o4 + ! save it a bit later so we do not waste a couple of cycles + rd %psr, %o2 st %o2, [%o0 + PSR_OFFSET] ! save status register + ! Now actually save ISR stack nesting prevention flag + st %o4, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET] + /* * This is entered from _CPU_Context_restore with: * o1 = context to restore * o2 = psr + * o3 = self per-CPU control */ PUBLIC(_CPU_Context_restore_heir) @@ -196,7 +199,6 @@ done_flushing: ! Load thread specific ISR dispatch prevention flag ld [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2 - sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %o3 ! Store it to memory later to use the cycles ldd [%o1 + L0_OFFSET], %l0 ! restore the local registers @@ -205,7 +207,7 @@ done_flushing: ldd [%o1 + L6_OFFSET], %l6 ! Now restore thread specific ISR dispatch prevention flag - st %o2,[%o3 + %lo(SYM(_CPU_ISR_Dispatch_disable))] + st %o2, [%o3 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE] ldd [%o1 + I0_OFFSET], %i0 ! restore the output registers ldd [%o1 + I2_OFFSET], %i2 @@ -235,6 +237,7 @@ done_flushing: SYM(_CPU_Context_restore): save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp rd %psr, %o2 + GET_SELF_CPU_CONTROL %o3, %o4 ba SYM(_CPU_Context_restore_heir) mov %i0, %o1 ! in the delay slot .align 4 @@ -591,11 +594,10 @@ dont_fix_pil2: orcc %l6, %g0, %g0 ! Is dispatching disabled? bnz simple_return ! Yes, then do a "simple" exit - ! NOTE: Use the delay slot - sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %l6 + nop ! Are we dispatching from a previous ISR in the interrupted thread? - ld [%l6 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %l7 + ld [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %l7 orcc %l7, %g0, %g0 ! Is this thread already doing an ISR? bnz simple_return ! Yes, then do a "simple" exit nop @@ -606,9 +608,9 @@ dont_fix_pil2: * return to the interrupt dispatcher. */ - ldub [%l5 + PER_CPU_DISPATCH_NEEDED], %l5 + ldub [%l5 + PER_CPU_DISPATCH_NEEDED], %l6 - orcc %l5, %g0, %g0 ! Is thread switch necessary? + orcc %l6, %g0, %g0 ! Is thread switch necessary? bz simple_return ! no, then do a simple return nop @@ -616,12 +618,9 @@ dont_fix_pil2: * Invoke interrupt dispatcher. */ - PUBLIC(_ISR_Dispatch) -SYM(_ISR_Dispatch): ! Set ISR dispatch nesting prevention flag mov 1,%l6 - sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %l5 - st %l6,[%l5 + %lo(SYM(_CPU_ISR_Dispatch_disable))] + st %l6, [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE] /* * The following subtract should get us back on the interrupted @@ -676,8 +675,7 @@ dispatchAgain: allow_nest_again: ! Zero out ISR stack nesting prevention flag - sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %l5 - st %g0,[%l5 + %lo(SYM(_CPU_ISR_Dispatch_disable))] + st %g0, [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE] /* * The CWP in place at this point may be different from diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c index baa15c0cbb..1865a21ee8 100644 --- a/cpukit/score/cpu/sparc/cpu.c +++ b/cpukit/score/cpu/sparc/cpu.c @@ -19,8 +19,15 @@ #include <rtems/system.h> #include <rtems/score/isr.h> +#include <rtems/score/percpu.h> #include <rtems/rtems/cache.h> +RTEMS_STATIC_ASSERT( + offsetof( Per_CPU_Control, cpu_per_cpu.isr_dispatch_disable) + == SPARC_PER_CPU_ISR_DISPATCH_DISABLE, + SPARC_PER_CPU_ISR_DISPATCH_DISABLE +); + /* * This initializes the set of opcodes placed in each trap * table entry. The routine which installs a handler is responsible @@ -65,13 +72,6 @@ void _CPU_Initialize(void) pointer = &_CPU_Null_fp_context; _CPU_Context_save_fp( &pointer ); #endif - - /* - * Since no tasks have been created yet and no interrupts have occurred, - * there is no way that the currently executing thread can have an - * _ISR_Dispatch stack frame on its stack. - */ - _CPU_ISR_Dispatch_disable = 0; } uint32_t _CPU_ISR_Get_level( void ) diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h index 61f041005f..690ddcf90c 100644 --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h @@ -357,7 +357,13 @@ typedef struct { /** This defines the size of the minimum stack frame. */ #define CPU_MINIMUM_STACK_FRAME_SIZE 0x60 -#define CPU_PER_CPU_CONTROL_SIZE 0 +#define CPU_PER_CPU_CONTROL_SIZE 4 + +/** + * @brief Offset of the CPU_Per_CPU_control::isr_dispatch_disable field + * relative to the Per_CPU_Control begin. + */ +#define SPARC_PER_CPU_ISR_DISPATCH_DISABLE 0 /** * @defgroup Contexts SPARC Context Structures @@ -383,7 +389,13 @@ typedef struct { #ifndef ASM typedef struct { - /* There is no CPU specific per-CPU state */ + /** + * This flag is context switched with each thread. It indicates + * that THIS thread has an _ISR_Dispatch stack frame on its stack. + * By using this flag, we can avoid nesting more interrupt dispatching + * attempts on a previously interrupted thread's stack. + */ + uint32_t isr_dispatch_disable; } CPU_Per_CPU_control; /** @@ -769,14 +781,6 @@ typedef struct { SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context CPU_STRUCTURE_ALIGNMENT; /** - * This flag is context switched with each thread. It indicates - * that THIS thread has an _ISR_Dispatch stack frame on its stack. - * By using this flag, we can avoid nesting more interrupt dispatching - * attempts on a previously interrupted thread's stack. - */ -SCORE_EXTERN volatile uint32_t _CPU_ISR_Dispatch_disable; - -/** * The following type defines an entry in the SPARC's trap table. * * NOTE: The instructions chosen are RTEMS dependent although one is |