forked from Imagelibrary/rtems
m68k software interrupt stack support from Chris Johns and Eric Norum.
This commit is contained in:
@@ -147,10 +147,6 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
void *isp = _CPU_Interrupt_stack_high;
|
void *isp = _CPU_Interrupt_stack_high;
|
||||||
|
|
||||||
asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
|
asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
|
||||||
#else
|
|
||||||
#warning "PLEASE IMPLEMENT ME... There is NO dedicated interrupt stack"
|
|
||||||
#warning "on CPUs without a dedicated hardware interrupt stack!!!"
|
|
||||||
#warning "INTERRUPTS RUN ON A TASK STACK!!!"
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,19 +34,16 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
* Use the m68k's hardware interrupt stack support and have the
|
* Use the m68k's hardware interrupt stack support and have the
|
||||||
* interrupt manager allocate the memory for it.
|
* interrupt manager allocate the memory for it.
|
||||||
*
|
|
||||||
* NOTE: The definitions when M68K_HAS_SEPARATE_STACKS is 0 should
|
|
||||||
* change when the software interrupt stack support is implemented.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if ( M68K_HAS_SEPARATE_STACKS == 1)
|
#if ( M68K_HAS_SEPARATE_STACKS == 1)
|
||||||
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
|
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 0
|
||||||
#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
|
#define CPU_HAS_HARDWARE_INTERRUPT_STACK 1
|
||||||
#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
|
#define CPU_ALLOCATE_INTERRUPT_STACK 1
|
||||||
#else
|
#else
|
||||||
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
|
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 1
|
||||||
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
|
#define CPU_HAS_HARDWARE_INTERRUPT_STACK 0
|
||||||
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
|
#define CPU_ALLOCATE_INTERRUPT_STACK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -108,9 +108,8 @@ norst: frestore a0@+ | restore the fp state frame
|
|||||||
* transfer control to the interrupt dispatcher.
|
* transfer control to the interrupt dispatcher.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* m68000 notes:
|
/*
|
||||||
*
|
* With this approach, lower priority interrupts may
|
||||||
* with this approach, lower interrupts (1-5 for efi68k) may
|
|
||||||
* execute twice if a higher priority interrupt is
|
* execute twice if a higher priority interrupt is
|
||||||
* acknowledged before _Thread_Dispatch_disable is
|
* acknowledged before _Thread_Dispatch_disable is
|
||||||
* increamented and the higher priority interrupt
|
* increamented and the higher priority interrupt
|
||||||
@@ -119,9 +118,6 @@ norst: frestore a0@+ | restore the fp state frame
|
|||||||
* higher priority interrupt in the new context if
|
* higher priority interrupt in the new context if
|
||||||
* permitted by the new interrupt level mask, and (2) when
|
* permitted by the new interrupt level mask, and (2) when
|
||||||
* the original context regains the cpu.
|
* the original context regains the cpu.
|
||||||
*
|
|
||||||
* XXX: Code for switching to a software maintained interrupt stack is
|
|
||||||
* not in place.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if ( M68K_HAS_VBR == 1)
|
#if ( M68K_HAS_VBR == 1)
|
||||||
@@ -141,22 +137,26 @@ norst: frestore a0@+ | restore the fp state frame
|
|||||||
|
|
||||||
SYM (_ISR_Handler):
|
SYM (_ISR_Handler):
|
||||||
addql #1,SYM (_Thread_Dispatch_disable_level) | disable multitasking
|
addql #1,SYM (_Thread_Dispatch_disable_level) | disable multitasking
|
||||||
addql #1,SYM (_ISR_Nest_level) | one nest level deeper
|
|
||||||
moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
|
moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE FOR CPUs WITHOUT HARDWARE INTERRUPT STACK:
|
|
||||||
*
|
|
||||||
* After the interrupted codes registers have been saved, it is save
|
|
||||||
* to switch to the software maintained interrupt stack.
|
|
||||||
*
|
|
||||||
* PLEASE, if you have a m68k without a dedicated interrupt stack,
|
|
||||||
* implement the stack switching code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
|
movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
|
||||||
andl #0x0fff,d0 | d0 = vector offset in vbr
|
andl #0x0fff,d0 | d0 = vector offset in vbr
|
||||||
|
|
||||||
|
|
||||||
|
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
||||||
|
movew sr,d1 | Save status register
|
||||||
|
oriw #0x700,sr | Disable interrupts
|
||||||
|
tstl SYM (_ISR_Nest_level) | Interrupting an interrupt handler?
|
||||||
|
bne 1f | Yes, just skip over stack switch code
|
||||||
|
movel SYM(_CPU_Interrupt_stack_high),a0 | End of interrupt stack
|
||||||
|
movel a7,a0@- | Save task stack pointer
|
||||||
|
movel a0,a7 | Switch to interrupt stack
|
||||||
|
1:
|
||||||
|
addql #1,SYM(_ISR_Nest_level) | one nest level deeper
|
||||||
|
movew d1,sr | Restore status register
|
||||||
|
#else
|
||||||
|
addql #1,SYM (_ISR_Nest_level) | one nest level deeper
|
||||||
|
#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
|
||||||
|
|
||||||
#if ( M68K_HAS_PREINDEXING == 1 )
|
#if ( M68K_HAS_PREINDEXING == 1 )
|
||||||
movel @( SYM (_ISR_Vector_table),d0:w:1),a0| fetch the ISR
|
movel @( SYM (_ISR_Vector_table),d0:w:1),a0| fetch the ISR
|
||||||
#else
|
#else
|
||||||
@@ -170,7 +170,18 @@ SYM (_ISR_Handler):
|
|||||||
jbsr a0@ | invoke the user ISR
|
jbsr a0@ | invoke the user ISR
|
||||||
addql #4,a7 | remove vector number
|
addql #4,a7 | remove vector number
|
||||||
|
|
||||||
subql #1,SYM (_ISR_Nest_level) | one less nest level
|
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
||||||
|
movew sr,d0 | Save status register
|
||||||
|
oriw #0x700,sr | Disable interrupts
|
||||||
|
subql #1,SYM(_ISR_Nest_level) | Reduce interrupt-nesting count
|
||||||
|
bne 1f | Skip if return to interrupt
|
||||||
|
movel (a7),a7 | Restore task stack pointer
|
||||||
|
1:
|
||||||
|
movew d0,sr | Restore status register
|
||||||
|
#else
|
||||||
|
subql #1,SYM (_ISR_Nest_level) | one less nest level
|
||||||
|
#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
|
||||||
|
|
||||||
subql #1,SYM (_Thread_Dispatch_disable_level)
|
subql #1,SYM (_Thread_Dispatch_disable_level)
|
||||||
| unnest multitasking
|
| unnest multitasking
|
||||||
bne exit | If dispatch disabled, exit
|
bne exit | If dispatch disabled, exit
|
||||||
|
|||||||
@@ -327,8 +327,8 @@ start:
|
|||||||
*/
|
*/
|
||||||
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
||||||
oriw #0x3000,sr | Switch to Master Stack Pointer
|
oriw #0x3000,sr | Switch to Master Stack Pointer
|
||||||
lea SYM(m360)+1024-64,a7 | Load stack pointer with space
|
lea SYM(m360)+1024-64,a7 | Put stack in dual-port ram
|
||||||
| for the Interrupt Stack
|
| a little below the interrupt stack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -327,8 +327,8 @@ start:
|
|||||||
*/
|
*/
|
||||||
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
||||||
oriw #0x3000,sr | Switch to Master Stack Pointer
|
oriw #0x3000,sr | Switch to Master Stack Pointer
|
||||||
lea SYM(m360)+1024-64,a7 | Load stack pointer with space
|
lea SYM(m360)+1024-64,a7 | Put stack in dual-port ram
|
||||||
| for the Interrupt Stack
|
| a little below the interrupt stack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -147,10 +147,6 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
void *isp = _CPU_Interrupt_stack_high;
|
void *isp = _CPU_Interrupt_stack_high;
|
||||||
|
|
||||||
asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
|
asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
|
||||||
#else
|
|
||||||
#warning "PLEASE IMPLEMENT ME... There is NO dedicated interrupt stack"
|
|
||||||
#warning "on CPUs without a dedicated hardware interrupt stack!!!"
|
|
||||||
#warning "INTERRUPTS RUN ON A TASK STACK!!!"
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user