From e0b8176076c2846e33f43b4523607af6f0ef9a31 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Fri, 11 Jul 2008 10:05:13 +0000 Subject: added support for mcf548x --- cpukit/score/cpu/m68k/cpu_asm.S | 112 +++++++++++++++++++++++++++++++ cpukit/score/cpu/m68k/rtems/asm.h | 11 +++ cpukit/score/cpu/m68k/rtems/score/cpu.h | 58 +++++++++++++++- cpukit/score/cpu/m68k/rtems/score/m68k.h | 4 ++ 4 files changed, 183 insertions(+), 2 deletions(-) (limited to 'cpukit/score/cpu/m68k') diff --git a/cpukit/score/cpu/m68k/cpu_asm.S b/cpukit/score/cpu/m68k/cpu_asm.S index a50ced6934..006922c227 100644 --- a/cpukit/score/cpu/m68k/cpu_asm.S +++ b/cpukit/score/cpu/m68k/cpu_asm.S @@ -15,6 +15,15 @@ #include + .data + +#if (defined(__mcoldfire__)) +#if ( M68K_HAS_FPU == 1 ) +PUBLIC (_CPU_cacr_shadow) +SYM (_CPU_cacr_shadow): + .long 1 +#endif +#endif .text @@ -35,6 +44,32 @@ SYM (_CPU_Context_switch): movml d1-d7/a2-a7,a0@ | save context moval a7@(HEIRCONTEXT_ARG),a0| a0 = heir thread context + +#if (defined(__mcoldfire__)) +#if ( M68K_HAS_FPU == 1 ) + moveb a0@(13*4),d0 | get context specific DF bit info in d0 + btstb #4,d0 | test context specific DF bit info + beq fpu_on | branch if FPU needs to be switched on + +fpu_off: movl _CPU_cacr_shadow,d0 | get content of _CPU_cacr_shadow in d0 + btstl #4,d0 | test DF bit info in d0 + bne restore | branch if FPU is already switched off + bsetl #4,d0 | set DF bit in d0 + bra cacr_set | branch to set the new FPU setting in cacr and _CPU_cacr_shadow + +fpu_on: movl _CPU_cacr_shadow,d0 | get content of _CPU_cacr_shadow in d1 + btstl #4,d0 | test context specific DF bit info + beq restore | branch if FPU is already switched on + bclrl #4,d0 | clear DF bit info in d0 + +cacr_set: movew sr,d1 | get content of sr in d1 + oril #0x00000700,d1 | mask d1 + movew d1,sr | disable all interrupts + movl d0,_CPU_cacr_shadow | move _CPU_cacr_shadow to d1 + movec d0,cacr | enable FPU in cacr +#endif +#endif + restore: movml a0@,d1-d7/a2-a7 | restore context movw d1,sr | restore status register rts @@ -66,6 +101,42 @@ restore: movml a0@,d1-d7/a2-a7 | restore context .global SYM (_CPU_Context_save_fp) SYM (_CPU_Context_save_fp): #if ( M68K_HAS_FPU == 1 ) +#if (defined(__mcoldfire__)) + + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area + moval a1@,a0 | a0 = Save context area + leal a0@(-16),a0 | open context frame for coldfire state frame + fsave a0@ | save coldfire state frame + tstb a0@ | check for a null frame + beq.b nosave | Yes, skip save of user model + leal a0@(-64),a0 | open context frame for coldfire data registers (fp0-fp7) + fmovem fp0-fp7,a0@ | save coldfire data registers (fp0-fp7) + movl #-1,a0@- | place not-null flag on stack +nosave: movl a0,a1@ | save pointer to saved context + +#if ( M68K_HAS_EMAC == 1 ) + + movel macsr,d0 | store content of macsr in d0 + clrl d1 | clear d1 + movl d1,macsr | disable rounding in macsr + movl acc0,d1 | store content of acc0 in d1 + moveml d0-d1,a0@(-8) | save EMAC macsr/acc0 + movl acc1,d0 | store acc1 in d0 + movl acc2,d1 | store acc2 in d1 + moveml d0-d1,a0@(-16) | save EMAC acc1/acc2 with offset + movl acc3,d0 | store acc3 in d0 + movl accext01,d1 | store acc2 in d1 + moveml d0-d1,a0@(-24) | save EMAC acc3/accext01 with offset + movl accext23,d0 | store accext23 in d0 + movl mask,d1 | store mask in d1 + moveml d0-d1,a0@(-32) | save EMAC accext23/mask with offset + leal a0@(-32),a0 | set a0 to the begin of coldfire data registers frame (fp0-fp7) + movl a0,a1@ | save pointer to saved context + +#endif + +#else + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area moval a1@,a0 | a0 = Save context area #if ( !defined(__mcoldfire__) && !__mc68060__ ) @@ -88,6 +159,8 @@ SYM (_CPU_Context_save_fp): #endif movl #-1,a0@- | place not-null flag on stack nosv: movl a0,a1@ | save pointer to saved context + +#endif #endif rts @@ -95,6 +168,43 @@ nosv: movl a0,a1@ | save pointer to saved context .global SYM (_CPU_Context_restore_fp) SYM (_CPU_Context_restore_fp): #if ( M68K_HAS_FPU == 1 ) + +#if (defined(__mcoldfire__)) + + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area + moval a1@,a0 | a0 = address of saved context + +#if ( M68K_HAS_EMAC == 1 ) + + clrl d0 | clear d0 + movl d0,macsr | disable roundrounding in macsr + moveml a0@(0),d0-d1 | get mask/accext23 in d0/d1 + movl d0,mask | restore mask + movl d1,accext23 | restore accext23 + moveml a0@(8),d0-d1 | get accext01/acc3 in d0/d1 + movl d0,accext01 | restore accext01 + movl d1,acc3 | restore acc3 + moveml a0@(16),d0-d1 | get acc2/acc1 in d0/d1 + movl d0,acc2 | restore acc2 + movl d1,acc1 | restore acc1 + moveml a0@(24),d0-d1 | get acc0/macsr in d0/d1 + movl d0,acc0 | restore acc0 + movl d1,macsr | restore macsr + leal a0@(32),a0 | set a0 to the begin of coldfire FPU frame + +#endif + + tstb a0@ | Null context frame? + beq.b norest | Yes, skip fp restore + addql #4,a0 | throwaway non-null flag + fmovem a0@,fp0-fp7 | restore data regs (fp0-fp7) + leal a0@(+64),a0 | close context frame for coldfire data registers (fp0-fp7) +norest: frestore a0@ | restore the fp state frame + leal a0@(+16),a0 | close context frame for coldfire state frame + movl a0,a1@ | save pointer to saved context + +#else + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area moval a1@,a0 | a0 = address of saved context tstb a0@ | Null context frame? @@ -114,6 +224,8 @@ norst: frestore a0@ | restore the fp state frame lea a0@(FP_STATE_SAVED),a0 #endif movl a0,a1@ | save pointer to saved context + +#endif #endif rts #endif diff --git a/cpukit/score/cpu/m68k/rtems/asm.h b/cpukit/score/cpu/m68k/rtems/asm.h index 9381607dac..851093480e 100644 --- a/cpukit/score/cpu/m68k/rtems/asm.h +++ b/cpukit/score/cpu/m68k/rtems/asm.h @@ -96,6 +96,17 @@ #define rambar0 REG (rambar0) #define mbar REG (mbar) +/* additional v4e special regs */ +#define rambar1 REG (rambar1) +#define macsr REG (macsr) +#define acc0 REG (acc0) +#define acc1 REG (acc1) +#define acc2 REG (acc2) +#define acc3 REG (acc3) +#define accext01 REG (accext01) +#define accext23 REG (accext23) +#define mask REG (mask) + #define fp0 REG (fp0) #define fp1 REG (fp1) diff --git a/cpukit/score/cpu/m68k/rtems/score/cpu.h b/cpukit/score/cpu/m68k/rtems/score/cpu.h index 084d2cf0c9..ddc7432032 100644 --- a/cpukit/score/cpu/m68k/rtems/score/cpu.h +++ b/cpukit/score/cpu/m68k/rtems/score/cpu.h @@ -133,6 +133,13 @@ typedef struct { void *a5; /* (a5) address register 5 */ void *a6; /* (a6) address register 6 */ void *a7_msp; /* (a7) master stack pointer */ + +#if (defined(__mcoldfire__)) +#if ( M68K_HAS_FPU == 1 ) + uint8_t fpu_dis; +#endif +#endif + } Context_Control; #define _CPU_Context_Get_SP( _context ) \ @@ -168,12 +175,35 @@ typedef struct { } _operand2; } Context_Control_fp; -#else +#elif (defined(__mcoldfire__)) /* - * FP context save area for the M68881/M68882 numeric coprocessors. + * FP context save area for the ColdFire core numeric coprocessors + */ +typedef struct { + uint8_t fp_save_area[84]; /* 16 bytes for FSAVE/FRESTORE */ + /* 64 bytes for FMOVEM FP0-7 */ + /* 4 bytes for non-null flag */ + +#if (M68K_HAS_EMAC == 1) + +/* + * EMAC context save area for the ColdFire core */ + uint8_t emac_save_area[32]; /* 32 bytes for EMAC registers */ + +#endif +} Context_Control_fp; + +#if ( M68K_HAS_FPU == 1 ) +extern uint32_t _CPU_cacr_shadow; +#endif + +#else +/* + * FP context save area for the M68881/M68882 numeric coprocessors. + */ typedef struct { uint8_t fp_save_area[332]; /* 216 bytes for FSAVE/FRESTORE */ /* 96 bytes for FMOVEM FP0-7 */ @@ -341,6 +371,7 @@ uint32_t _CPU_ISR_Get_level( void ); * + initialize an FP context area */ +#if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 )) #define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ _isr, _entry_point, _is_fp ) \ do { \ @@ -350,7 +381,20 @@ uint32_t _CPU_ISR_Get_level( void ); _stack = (uint32_t )(_stack_base) + (_size) - 4; \ (_the_context)->a7_msp = (void *)_stack; \ *(void **)_stack = (void *)(_entry_point); \ + (_the_context)->fpu_dis = (_is_fp == TRUE) ? 0x00 : 0x10; \ } while ( 0 ) +#else +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _isr, _entry_point, _is_fp ) \ + do { \ + uint32_t _stack; \ + \ + (_the_context)->sr = 0x3000 | ((_isr) << 8); \ + _stack = (uint32_t )(_stack_base) + (_size) - 4; \ + (_the_context)->a7_msp = (void *)_stack; \ + *(void **)_stack = (void *)(_entry_point); \ + } while ( 0 ) +#endif #define _CPU_Context_Restart_self( _the_context ) \ { asm volatile( "movew %0,%%sr ; " \ @@ -396,12 +440,22 @@ uint32_t _CPU_ISR_Get_level( void ); ) \ ) +#if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 )) #define _CPU_Context_Initialize_fp( _fp_area ) \ { uint32_t *_fp_context = (uint32_t *)*(_fp_area); \ \ *(--(_fp_context)) = 0; \ *(_fp_area) = (uint8_t *)(_fp_context); \ + asm volatile("movl %0,%%macsr": : "d" (0) ); \ } +#else +#define _CPU_Context_Initialize_fp( _fp_area ) \ + { uint32_t *_fp_context = (uint32_t *)*(_fp_area); \ + \ + *(--(_fp_context)) = 0; \ + *(_fp_area) = (uint8_t *)(_fp_context); \ + } +#endif #endif /* end of Context handler macros */ diff --git a/cpukit/score/cpu/m68k/rtems/score/m68k.h b/cpukit/score/cpu/m68k/rtems/score/m68k.h index 2a501d64c8..85cf70b1a7 100644 --- a/cpukit/score/cpu/m68k/rtems/score/m68k.h +++ b/cpukit/score/cpu/m68k/rtems/score/m68k.h @@ -130,6 +130,10 @@ extern "C" { */ # if defined (__mcffpu__) # define M68K_HAS_FPU 1 + /* + * td: can we be sure that all CFs with FPU also have an EMAC? + */ +# define M68K_HAS_EMAC 1 # define M68K_HAS_FPSP_PACKAGE 0 # else # define M68K_HAS_FPU 0 -- cgit v1.2.3