mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
Coldfire support patch from David Fiddes <D.J.Fiddes@hw.ac.uk>.
This commit is contained in:
@@ -391,11 +391,25 @@ unsigned32 _CPU_ISR_Get_level( void );
|
||||
* + disable interrupts and halt the CPU
|
||||
*/
|
||||
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define _CPU_Fatal_halt( _error ) \
|
||||
{ asm volatile( "move.w %%sr,%%d0\n\t" \
|
||||
"or.l %2,%%d0\n\t" \
|
||||
"move.w %%d0,%%sr\n\t" \
|
||||
"move.l %1,%%d0\n\t" \
|
||||
"move.l #0xDEADBEEF,%%d1\n\t" \
|
||||
"halt" \
|
||||
: "=g" (_error) \
|
||||
: "0" (_error), "d"(0x0700) \
|
||||
: "d0", "d1" ); \
|
||||
}
|
||||
#else
|
||||
#define _CPU_Fatal_halt( _error ) \
|
||||
{ asm volatile( "movl %0,%%d0; " \
|
||||
"orw #0x0700,%%sr; " \
|
||||
"stop #0x2700" : "=d" ((_error)) : "0" ((_error)) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end of Fatal Error manager macros */
|
||||
|
||||
@@ -425,7 +439,28 @@ unsigned32 _CPU_ISR_Get_level( void );
|
||||
/* duplicates BFFFO results for 16 bits (i.e., 15-(_priority) in
|
||||
_CPU_Priority_bits_index is not needed), handles the 0 case, and
|
||||
does not molest _value -- jsg */
|
||||
#if ( M68K_HAS_EXTB_L == 1 )
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
|
||||
{ \
|
||||
extern const unsigned char __BFFFOtable[256]; \
|
||||
register int dumby; \
|
||||
\
|
||||
asm volatile ( \
|
||||
" clr.l %1\n" \
|
||||
" move.w %2,%1\n" \
|
||||
" lsr.l #8,%1\n" \
|
||||
" beq.s 1f\n" \
|
||||
" move.b (%3,%1),%0\n" \
|
||||
" bra.s 0f\n" \
|
||||
"1: move.w %2,%1\n" \
|
||||
" move.b (%3,%1),%0\n" \
|
||||
" addq.l #8,%0\n" \
|
||||
"0: and.l #0xff,%0\n" \
|
||||
: "=&d" ((_output)), "=&d" ((dumby)) \
|
||||
: "d" ((_value)), "ao" ((__BFFFOtable)) \
|
||||
: "cc" ) ; \
|
||||
}
|
||||
#elif ( M68K_HAS_EXTB_L == 1 )
|
||||
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
|
||||
{ \
|
||||
extern const unsigned char __BFFFOtable[256]; \
|
||||
@@ -463,7 +498,7 @@ unsigned32 _CPU_ISR_Get_level( void );
|
||||
: "d" ((_value)), "ao" ((__BFFFOtable)) \
|
||||
: "cc" ) ; \
|
||||
}
|
||||
#endif /* M68K_HAS_EXTB_L */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -120,7 +120,11 @@ norst: frestore a0@+ | restore the fp state frame
|
||||
* the original context regains the cpu.
|
||||
*/
|
||||
|
||||
#if ( M68K_HAS_VBR == 1)
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
.set SR_OFFSET, 2 | Status register offset
|
||||
.set PC_OFFSET, 4 | Program Counter offset
|
||||
.set FVO_OFFSET, 0 | Format/vector offset
|
||||
#elif ( M68K_HAS_VBR == 1)
|
||||
.set SR_OFFSET, 0 | Status register offset
|
||||
.set PC_OFFSET, 2 | Program Counter offset
|
||||
.set FVO_OFFSET, 6 | Format/vector offset
|
||||
@@ -137,14 +141,31 @@ norst: frestore a0@+ | restore the fp state frame
|
||||
|
||||
SYM (_ISR_Handler):
|
||||
addql #1,SYM (_Thread_Dispatch_disable_level) | disable multitasking
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
|
||||
movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
|
||||
andl #0x0fff,d0 | d0 = vector offset in vbr
|
||||
#else
|
||||
lea a7@(-SAVED),a7
|
||||
movm.l d0-d1/a0-a1,a7@ | save d0-d1,a0-a1
|
||||
movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
|
||||
andl #0x0ffc,d0 | d0 = vector offset in vbr
|
||||
#endif
|
||||
|
||||
|
||||
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
movew sr,d1 | Save status register
|
||||
oriw #0x700,sr | Disable interrupts
|
||||
#else
|
||||
move.l d0,a7@- | Save d0 value
|
||||
move.l 0x700,d0 | Load in disable ints value
|
||||
move.w sr,d1 | Grab SR
|
||||
or.l d1,d0 | Create new SR
|
||||
move.w d0,sr | Disable interrupts
|
||||
move.l a7@+,d0 | Restore d0 value
|
||||
#endif
|
||||
|
||||
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
|
||||
@@ -171,8 +192,16 @@ SYM (_ISR_Handler):
|
||||
addql #4,a7 | remove vector number
|
||||
|
||||
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
movew sr,d0 | Save status register
|
||||
oriw #0x700,sr | Disable interrupts
|
||||
#else
|
||||
move.l 0x700,d1 | Load in disable int value
|
||||
move.w sr,d0 | Grab SR
|
||||
or.l d0,d1 | Create new SR
|
||||
move.w d1,sr | Load to disable interrupts
|
||||
#endif
|
||||
|
||||
subql #1,SYM(_ISR_Nest_level) | Reduce interrupt-nesting count
|
||||
bne 1f | Skip if return to interrupt
|
||||
movel (a7),a7 | Restore task stack pointer
|
||||
@@ -215,7 +244,13 @@ bframe: clrl SYM (_ISR_Signals_to_thread_executing)
|
||||
jsr SYM (_Thread_Dispatch) | Perform context switch
|
||||
#endif
|
||||
|
||||
exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
#else
|
||||
exit: moveml a7@,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
lea a7@(SAVED),a7
|
||||
#endif
|
||||
|
||||
#if ( M68K_HAS_VBR == 0 )
|
||||
addql #2,a7 | pop format/id
|
||||
#endif /* M68K_HAS_VBR */
|
||||
@@ -238,9 +273,18 @@ exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
||||
|
||||
.global SYM (_ISR_Dispatch)
|
||||
SYM (_ISR_Dispatch):
|
||||
#if ( M68K_COLDFIRE_ARCH == 0 )
|
||||
movml d0-d1/a0-a1,a7@-
|
||||
jsr SYM (_Thread_Dispatch)
|
||||
movml a7@+,d0-d1/a0-a1
|
||||
#else
|
||||
lea a7@(-SAVED),a7
|
||||
movml d0-d1/a0-a1,a7@
|
||||
jsr SYM (_Thread_Dispatch)
|
||||
movml a7@,d0-d1/a0-a1
|
||||
lea a7@(SAVED),a7
|
||||
#endif
|
||||
|
||||
#if ( M68K_HAS_VBR == 0 )
|
||||
addql #2,a7 | pop format/id
|
||||
#endif /* M68K_HAS_VBR */
|
||||
|
||||
@@ -40,6 +40,7 @@ extern "C" {
|
||||
* -m68302 (no FP) (deprecated, use -m68000)
|
||||
* -m68332 (no FP) (deprecated, use -mcpu32)
|
||||
* -mcpu32 (no FP)
|
||||
* -m5200 (no FP)
|
||||
*
|
||||
* As of gcc 2.8.1 and egcs 1.1, there is no distinction made between
|
||||
* the CPU32 and CPU32+. The option -mcpu32 generates code which can
|
||||
@@ -164,6 +165,19 @@ extern "C" {
|
||||
#define M68K_HAS_FPU 0
|
||||
#define M68K_HAS_FPSP_PACKAGE 0
|
||||
|
||||
#elif defined(__mcf5200__)
|
||||
/* Motorola ColdFire V2 core - RISC/68020 hybrid */
|
||||
#define CPU_MODEL_NAME "m5200"
|
||||
#define M68K_HAS_VBR 1
|
||||
#define M68K_HAS_BFFFO 0
|
||||
#define M68K_HAS_SEPARATE_STACKS 0
|
||||
#define M68K_HAS_PREINDEXING 0
|
||||
#define M68K_HAS_EXTB_L 1
|
||||
#define M68K_HAS_MISALIGNED 1
|
||||
#define M68K_HAS_FPU 0
|
||||
#define M68K_HAS_FPSP_PACKAGE 0
|
||||
#define M68K_COLDFIRE_ARCH 1
|
||||
|
||||
#elif defined(__mc68000__)
|
||||
|
||||
#define CPU_MODEL_NAME "m68000"
|
||||
@@ -187,32 +201,65 @@ extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the above did not specify a ColdFire architecture, then set
|
||||
* this flag to indicate that it is not a ColdFire CPU.
|
||||
*/
|
||||
|
||||
#if !defined(M68K_COLDFIRE_ARCH)
|
||||
#define M68K_COLDFIRE_ARCH 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the name of the CPU family.
|
||||
*/
|
||||
|
||||
#define CPU_NAME "Motorola MC68xxx"
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define CPU_NAME "Motorola ColdFire"
|
||||
#else
|
||||
#define CPU_NAME "Motorola MC68xxx"
|
||||
#endif
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define m68k_disable_interrupts( _level ) \
|
||||
asm volatile ( "movew %%sr,%0\n\t" \
|
||||
"orw #0x0700,%%sr" \
|
||||
do { register unsigned32 _tmpsr = 0x0700; \
|
||||
asm volatile ( "move.w %%sr,%0\n\t" \
|
||||
"or.l %0,%1\n\t" \
|
||||
"move.w %1,%%sr" \
|
||||
: "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) ); \
|
||||
} while( 0 )
|
||||
#else
|
||||
#define m68k_disable_interrupts( _level ) \
|
||||
asm volatile ( "move.w %%sr,%0\n\t" \
|
||||
"or.w #0x0700,%%sr" \
|
||||
: "=d" (_level))
|
||||
#endif
|
||||
|
||||
#define m68k_enable_interrupts( _level ) \
|
||||
asm volatile ( "movew %0,%%sr " : : "d" (_level));
|
||||
asm volatile ( "move.w %0,%%sr " : : "d" (_level));
|
||||
|
||||
#if ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define m68k_flash_interrupts( _level ) \
|
||||
asm volatile ( "movew %0,%%sr\n\t" \
|
||||
"orw #0x0700,%%sr" \
|
||||
do { register unsigned32 _tmpsr = 0x0700; \
|
||||
asm volatile ( "move.w %2,%%sr\n\t" \
|
||||
"or.l %2,%1\n\t" \
|
||||
"move.w %1,%%sr" \
|
||||
: "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) ); \
|
||||
} while( 0 )
|
||||
#else
|
||||
#define m68k_flash_interrupts( _level ) \
|
||||
asm volatile ( "move.w %0,%%sr\n\t" \
|
||||
"or.w #0x0700,%%sr" \
|
||||
: : "d" (_level))
|
||||
#endif
|
||||
|
||||
#define m68k_get_interrupt_level( _level ) \
|
||||
do { \
|
||||
register unsigned32 _tmpsr; \
|
||||
\
|
||||
asm volatile( "movw %%sr,%0" : "=d" (_tmpsr)); \
|
||||
asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
|
||||
_level = (_tmpsr & 0x0700) >> 8; \
|
||||
} while (0)
|
||||
|
||||
@@ -220,17 +267,28 @@ extern "C" {
|
||||
do { \
|
||||
register unsigned32 _tmpsr; \
|
||||
\
|
||||
asm volatile( "movw %%sr,%0" : "=d" (_tmpsr)); \
|
||||
asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
|
||||
_tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
|
||||
asm volatile( "movw %0,%%sr" : : "d" (_tmpsr)); \
|
||||
asm volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \
|
||||
} while (0)
|
||||
|
||||
#if ( M68K_HAS_VBR == 1 )
|
||||
#if ( M68K_HAS_VBR == 1 && M68K_COLDFIRE_ARCH == 0 )
|
||||
#define m68k_get_vbr( vbr ) \
|
||||
asm volatile ( "movec %%vbr,%0 " : "=r" (vbr))
|
||||
|
||||
#define m68k_set_vbr( vbr ) \
|
||||
asm volatile ( "movec %0,%%vbr " : : "r" (vbr))
|
||||
|
||||
#elif ( M68K_COLDFIRE_ARCH == 1 )
|
||||
#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
|
||||
|
||||
#define m68k_set_vbr( _vbr ) \
|
||||
asm volatile ("move.l %%a7,%%d1 \n\t" \
|
||||
"move.l %0,%%a7\n\t" \
|
||||
"movec %%a7,%%vbr\n\t" \
|
||||
"move.l %%d1,%%a7\n\t" \
|
||||
: : "d" (_vbr) : "d1" );
|
||||
|
||||
#else
|
||||
#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
|
||||
#define m68k_set_vbr( _vbr )
|
||||
|
||||
Reference in New Issue
Block a user