Update from Philip Quaife <rtemsdev@qs.co.nz> that was hand-merged.

This update addresses the following:

  + the ISR enable/disable/flash macros now work with old gcc versions.
  + the UI CCR bits are now masked since other example code did so
  + _ISR_Dispatch disables interrupts during call setup

Together these removed the instabilities he was seeing.
This commit is contained in:
Joel Sherrill
2000-07-17 13:01:44 +00:00
parent 237c259851
commit fb31e1a2e7
4 changed files with 150 additions and 68 deletions

View File

@@ -18,7 +18,6 @@
;.equ RUNCONTEXT_ARG, er0 ;.equ RUNCONTEXT_ARG, er0
;.equ HEIRCONTEXT_ARG, er1 ;.equ HEIRCONTEXT_ARG, er1
/* /*
* Make sure we tell the assembler what type of CPU model we are * Make sure we tell the assembler what type of CPU model we are
* being compiled for. * being compiled for.
@@ -32,6 +31,7 @@
#endif #endif
.text .text
.text
/* /*
GCC Compiled with optimisations and Wimplicit decs to ensure GCC Compiled with optimisations and Wimplicit decs to ensure
that stack from doesn't change that stack from doesn't change
@@ -43,11 +43,12 @@
*/ */
.align 2 .align 2
.global __CPU_Context_switch .global __CPU_Context_switch
__CPU_Context_switch: __CPU_Context_switch:
#if defined(__H8300H__) || defined(__H8300S__)
/* Save Context */ /* Save Context */
stc ccr,@(0:16,er0) stc.w ccr,@(0:16,er0)
mov.l er7,@(2:16,er0) mov.l er7,@(2:16,er0)
mov.l er6,@(6:16,er0) mov.l er6,@(6:16,er0)
mov.l er5,@(10:16,er0) mov.l er5,@(10:16,er0)
@@ -64,19 +65,18 @@ restore:
mov.l @(10:16,er1),er5 mov.l @(10:16,er1),er5
mov.l @(6:16,er1),er6 mov.l @(6:16,er1),er6
mov.l @(2:16,er1),er7 mov.l @(2:16,er1),er7
ldc @(0:16,er1),ccr ldc.w @(0:16,er1),ccr
#endif
rts rts
.align 2 .align 2
.global __CPU_Context_restore .global __CPU_Context_restore
__CPU_Context_restore: __CPU_Context_restore:
#if defined(__H8300H__) || defined(__H8300S__)
mov.l er0,er1 Mov.l er0,er1
jmp @restore:24 jmp @restore:24
#else
rts
#endif
@@ -96,7 +96,6 @@ __CPU_Context_restore:
__ISR_Handler: __ISR_Handler:
#if defined(__H8300H__) || defined(__H8300S__)
mov.l er1,@-er7 mov.l er1,@-er7
mov.l er2,@-er7 mov.l er2,@-er7
mov.l er3,@-er7 mov.l er3,@-er7
@@ -105,7 +104,7 @@ __ISR_Handler:
mov.l er6,@-er7 mov.l er6,@-er7
/* Set IRQ Stack */ /* Set IRQ Stack */
orc #0x80,ccr orc #0xc0,ccr
mov.l er7,er6 ; save stack pointer mov.l er7,er6 ; save stack pointer
mov.l @__ISR_Nest_level,er1 mov.l @__ISR_Nest_level,er1
bne nested bne nested
@@ -132,7 +131,7 @@ nested:
mov.l @er1,er1 mov.l @er1,er1
jsr @er1 ; er0 = arg1 =vector jsr @er1 ; er0 = arg1 =vector
orc #0x80,ccr orc #0xc0,ccr
mov.l @__ISR_Nest_level,er1 mov.l @__ISR_Nest_level,er1
dec.l #1,er1 dec.l #1,er1
mov.l er1,@__ISR_Nest_level mov.l er1,@__ISR_Nest_level
@@ -150,7 +149,7 @@ nested:
/* Context switch here through ISR_Dispatch */ /* Context switch here through ISR_Dispatch */
bframe: bframe:
orc #0x80,ccr orc #0xc0,ccr
/* Pop Stack */ /* Pop Stack */
mov @er7+,er6 mov @er7+,er6
mov er6,er7 mov er6,er7
@@ -159,12 +158,7 @@ bframe:
/* Set up IRQ stack frame and dispatch to _ISR_Dispatch */ /* Set up IRQ stack frame and dispatch to _ISR_Dispatch */
stc ccr,@er2 mov.l #0xc0000000,er2 /* Disable IRQ */
and.l #0xff,er2
rotr.l er2
rotr.l er2
rotr.l er2
rotr.l er2
or.l #_ISR_Dispatch,er2 or.l #_ISR_Dispatch,er2
mov.l er2,@-er7 mov.l er2,@-er7
rte rte
@@ -175,7 +169,6 @@ exit:
orc #0x80,ccr orc #0x80,ccr
mov @er7+,er6 mov @er7+,er6
mov er6,er7 mov er6,er7
andc #0x7f,ccr
mov @er7+,er6 mov @er7+,er6
mov @er7+,er5 mov @er7+,er5
mov @er7+,er4 mov @er7+,er4
@@ -183,23 +176,22 @@ exit:
mov @er7+,er2 mov @er7+,er2
mov @er7+,er1 mov @er7+,er1
mov @er7+,er0 mov @er7+,er0
andc #0x7f,ccr
rte rte
#endif
/* /*
Called from ISR_Handler as a way of ending IRQ Called from ISR_Handler as a way of ending IRQ
but allowing dispatch to another task. but allowing dispatch to another task.
Must use RTE as CCR is still on stack but IRQ has been serviced. Must use RTE as CCR is still on stack but IRQ has been serviced.
CCR and PC occupy same word so rte can be used. CCR and PC occupy same word so rte can be used.
now using task stack
*/ */
.align 2 .align 2
.global _ISR_Dispatch .global _ISR_Dispatch
_ISR_Dispatch: _ISR_Dispatch:
#if defined(__H8300H__) || defined(__H8300S__)
jsr @__Thread_Dispatch Jsr @__Thread_Dispatch
mov @er7+,er6 mov @er7+,er6
mov @er7+,er5 mov @er7+,er5
mov @er7+,er4 mov @er7+,er4
@@ -208,7 +200,6 @@ _ISR_Dispatch:
mov @er7+,er1 mov @er7+,er1
mov @er7+,er0 mov @er7+,er0
rte rte
#endif
.align 2 .align 2

View File

@@ -603,13 +603,61 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
/* ISR handler macros */ /* ISR handler macros */
/* COPE With Brain dead version of GCC distributed with Hitachi HIView Tools.
Note requires ISR_Level be unsigned16 or assembler croaks.
*/
#if (__GNUC__ == 2 && __GNUC_MINOR__ == 7 )
/*
* Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _isr_cookie ) \
do { \
asm volatile( "stc.w ccr, @-er7 ;\n orc #0xC0,ccr ;\n mov.w @er7+,%0" : : "r" (_isr_cookie) ); \
} while (0)
/*
* Enable interrupts to the previois level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
* _level is not modified.
*/
#define _CPU_ISR_Enable( _isr_cookie ) \
do { \
asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr" : : "r" (_isr_cookie) ); \
} while (0)
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
* sections into two or more parts. The parameter _level is not
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
do { \
asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr ;\n orc #0xC0,ccr" : : "r" (_isr_cookie) ); \
} while (0)
/* end of ISR handler macros */
#else
/* /*
* Disable all interrupts for an RTEMS critical section. The previous * Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level. * level is returned in _level.
* *
* H8300 Specific Information: * H8300 Specific Information:
* *
* XXX FIXME this does not nest properly for the H8300. * XXX
*/ */
#if defined(__H8300__) #if defined(__H8300__)
@@ -669,6 +717,8 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
} while (0) } while (0)
#endif #endif
#endif /* end of old gcc */
/* /*
* Map interrupt level in task mode onto the hardware that the CPU * Map interrupt level in task mode onto the hardware that the CPU

View File

@@ -18,7 +18,6 @@
;.equ RUNCONTEXT_ARG, er0 ;.equ RUNCONTEXT_ARG, er0
;.equ HEIRCONTEXT_ARG, er1 ;.equ HEIRCONTEXT_ARG, er1
/* /*
* Make sure we tell the assembler what type of CPU model we are * Make sure we tell the assembler what type of CPU model we are
* being compiled for. * being compiled for.
@@ -32,6 +31,7 @@
#endif #endif
.text .text
.text
/* /*
GCC Compiled with optimisations and Wimplicit decs to ensure GCC Compiled with optimisations and Wimplicit decs to ensure
that stack from doesn't change that stack from doesn't change
@@ -43,11 +43,12 @@
*/ */
.align 2 .align 2
.global __CPU_Context_switch .global __CPU_Context_switch
__CPU_Context_switch: __CPU_Context_switch:
#if defined(__H8300H__) || defined(__H8300S__)
/* Save Context */ /* Save Context */
stc ccr,@(0:16,er0) stc.w ccr,@(0:16,er0)
mov.l er7,@(2:16,er0) mov.l er7,@(2:16,er0)
mov.l er6,@(6:16,er0) mov.l er6,@(6:16,er0)
mov.l er5,@(10:16,er0) mov.l er5,@(10:16,er0)
@@ -64,19 +65,18 @@ restore:
mov.l @(10:16,er1),er5 mov.l @(10:16,er1),er5
mov.l @(6:16,er1),er6 mov.l @(6:16,er1),er6
mov.l @(2:16,er1),er7 mov.l @(2:16,er1),er7
ldc @(0:16,er1),ccr ldc.w @(0:16,er1),ccr
#endif
rts rts
.align 2 .align 2
.global __CPU_Context_restore .global __CPU_Context_restore
__CPU_Context_restore: __CPU_Context_restore:
#if defined(__H8300H__) || defined(__H8300S__)
mov.l er0,er1 Mov.l er0,er1
jmp @restore:24 jmp @restore:24
#else
rts
#endif
@@ -96,7 +96,6 @@ __CPU_Context_restore:
__ISR_Handler: __ISR_Handler:
#if defined(__H8300H__) || defined(__H8300S__)
mov.l er1,@-er7 mov.l er1,@-er7
mov.l er2,@-er7 mov.l er2,@-er7
mov.l er3,@-er7 mov.l er3,@-er7
@@ -105,7 +104,7 @@ __ISR_Handler:
mov.l er6,@-er7 mov.l er6,@-er7
/* Set IRQ Stack */ /* Set IRQ Stack */
orc #0x80,ccr orc #0xc0,ccr
mov.l er7,er6 ; save stack pointer mov.l er7,er6 ; save stack pointer
mov.l @__ISR_Nest_level,er1 mov.l @__ISR_Nest_level,er1
bne nested bne nested
@@ -132,7 +131,7 @@ nested:
mov.l @er1,er1 mov.l @er1,er1
jsr @er1 ; er0 = arg1 =vector jsr @er1 ; er0 = arg1 =vector
orc #0x80,ccr orc #0xc0,ccr
mov.l @__ISR_Nest_level,er1 mov.l @__ISR_Nest_level,er1
dec.l #1,er1 dec.l #1,er1
mov.l er1,@__ISR_Nest_level mov.l er1,@__ISR_Nest_level
@@ -150,7 +149,7 @@ nested:
/* Context switch here through ISR_Dispatch */ /* Context switch here through ISR_Dispatch */
bframe: bframe:
orc #0x80,ccr orc #0xc0,ccr
/* Pop Stack */ /* Pop Stack */
mov @er7+,er6 mov @er7+,er6
mov er6,er7 mov er6,er7
@@ -159,12 +158,7 @@ bframe:
/* Set up IRQ stack frame and dispatch to _ISR_Dispatch */ /* Set up IRQ stack frame and dispatch to _ISR_Dispatch */
stc ccr,@er2 mov.l #0xc0000000,er2 /* Disable IRQ */
and.l #0xff,er2
rotr.l er2
rotr.l er2
rotr.l er2
rotr.l er2
or.l #_ISR_Dispatch,er2 or.l #_ISR_Dispatch,er2
mov.l er2,@-er7 mov.l er2,@-er7
rte rte
@@ -175,7 +169,6 @@ exit:
orc #0x80,ccr orc #0x80,ccr
mov @er7+,er6 mov @er7+,er6
mov er6,er7 mov er6,er7
andc #0x7f,ccr
mov @er7+,er6 mov @er7+,er6
mov @er7+,er5 mov @er7+,er5
mov @er7+,er4 mov @er7+,er4
@@ -183,23 +176,22 @@ exit:
mov @er7+,er2 mov @er7+,er2
mov @er7+,er1 mov @er7+,er1
mov @er7+,er0 mov @er7+,er0
andc #0x7f,ccr
rte rte
#endif
/* /*
Called from ISR_Handler as a way of ending IRQ Called from ISR_Handler as a way of ending IRQ
but allowing dispatch to another task. but allowing dispatch to another task.
Must use RTE as CCR is still on stack but IRQ has been serviced. Must use RTE as CCR is still on stack but IRQ has been serviced.
CCR and PC occupy same word so rte can be used. CCR and PC occupy same word so rte can be used.
now using task stack
*/ */
.align 2 .align 2
.global _ISR_Dispatch .global _ISR_Dispatch
_ISR_Dispatch: _ISR_Dispatch:
#if defined(__H8300H__) || defined(__H8300S__)
jsr @__Thread_Dispatch Jsr @__Thread_Dispatch
mov @er7+,er6 mov @er7+,er6
mov @er7+,er5 mov @er7+,er5
mov @er7+,er4 mov @er7+,er4
@@ -208,7 +200,6 @@ _ISR_Dispatch:
mov @er7+,er1 mov @er7+,er1
mov @er7+,er0 mov @er7+,er0
rte rte
#endif
.align 2 .align 2

View File

@@ -603,13 +603,61 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
/* ISR handler macros */ /* ISR handler macros */
/* COPE With Brain dead version of GCC distributed with Hitachi HIView Tools.
Note requires ISR_Level be unsigned16 or assembler croaks.
*/
#if (__GNUC__ == 2 && __GNUC_MINOR__ == 7 )
/*
* Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _isr_cookie ) \
do { \
asm volatile( "stc.w ccr, @-er7 ;\n orc #0xC0,ccr ;\n mov.w @er7+,%0" : : "r" (_isr_cookie) ); \
} while (0)
/*
* Enable interrupts to the previois level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
* _level is not modified.
*/
#define _CPU_ISR_Enable( _isr_cookie ) \
do { \
asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr" : : "r" (_isr_cookie) ); \
} while (0)
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
* sections into two or more parts. The parameter _level is not
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
do { \
asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr ;\n orc #0xC0,ccr" : : "r" (_isr_cookie) ); \
} while (0)
/* end of ISR handler macros */
#else
/* /*
* Disable all interrupts for an RTEMS critical section. The previous * Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level. * level is returned in _level.
* *
* H8300 Specific Information: * H8300 Specific Information:
* *
* XXX FIXME this does not nest properly for the H8300. * XXX
*/ */
#if defined(__H8300__) #if defined(__H8300__)
@@ -669,6 +717,8 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
} while (0) } while (0)
#endif #endif
#endif /* end of old gcc */
/* /*
* Map interrupt level in task mode onto the hardware that the CPU * Map interrupt level in task mode onto the hardware that the CPU