diff options
author | Till Straumann <strauman@slac.stanford.edu> | 2005-12-02 02:47:23 +0000 |
---|---|---|
committer | Till Straumann <strauman@slac.stanford.edu> | 2005-12-02 02:47:23 +0000 |
commit | d8ada5b617c70f3b94a3c6117958b62e8e0cb9e4 (patch) | |
tree | c3f1eda21f8ba34740ee482fb6a03beba3c725fa /c | |
parent | 2005-11-29 Till Straumann <strauman@slac.stanford.edu> (diff) | |
download | rtems-d8ada5b617c70f3b94a3c6117958b62e8e0cb9e4.tar.bz2 |
2005-12-01 Till Straumann <strauman@slac.stanford.edu>
* shared/vectors/vectors.h, shared/vectors/vectors.S,
shared/vectors/vectors_init.c: Reduced size of default
prologue (some exceptions, e.g., altivec unavail.) are only
0x20 bytes apart. Also introduced a modified prologue
that switches r0..r3 shadowing off (r0..r3 undefined
on certain 603e variants when incurring a TLB miss).
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ChangeLog | 8 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/vectors/vectors.S | 65 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/vectors/vectors.h | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c | 23 |
4 files changed, 72 insertions, 26 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog index d1351984fa..f90411188e 100644 --- a/c/src/lib/libbsp/powerpc/ChangeLog +++ b/c/src/lib/libbsp/powerpc/ChangeLog @@ -1,3 +1,11 @@ +2005-12-01 Till Straumann <strauman@slac.stanford.edu> + * shared/vectors/vectors.h, shared/vectors/vectors.S, + shared/vectors/vectors_init.c: Reduced size of default + prologue (some exceptions, e.g., altivec unavail.) are only + 0x20 bytes apart. Also introduced a modified prologue + that switches r0..r3 shadowing off (r0..r3 undefined + on certain 603e variants when incurring a TLB miss). + 2005-11-29 Till Straumann <strauman@slac.stanford.edu> * shared/irq/irq_asm.S, shared/vectors/vectors.S: Clear CR[6] before invoking high-level handler to make sure no diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S index 8dba3a3926..96a4be5386 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S @@ -11,6 +11,7 @@ #include <rtems/asm.h> #include <rtems/score/cpu.h> #include <bsp/vectors.h> +#include <libcpu/raw_exception.h> #define SYNC \ sync; \ @@ -28,50 +29,68 @@ SYM (__rtems_start): * end of special Entry point section */ .text - .p2align 5 - + /* 603e shadows GPR0..GPR3 for certain exceptions. We must switch + * that off before we can use the stack pointer. Note that this is + * ONLY safe if the shadowing is actually active -- otherwise, r1 + * is destroyed. We deliberately use r1 so problems become obvious + * if this is abused! + */ +PUBLIC_VAR(tgpr_clr_exception_vector_code_prolog) +SYM (tgpr_clr_exception_vector_code_prolog): + mfmsr r1 + rlwinm r1,r1,0,15,13 + mtmsr r1 + isync + /* fall thru */ PUBLIC_VAR(default_exception_vector_code_prolog) SYM (default_exception_vector_code_prolog): /* * let room for exception frame */ - stwu r1, - (EXCEPTION_FRAME_END)(r1) - stw r3, GPR3_OFFSET(r1) - /* R2 should never change (EABI: pointer to .sdata2) - we - * save it nevertheless.. - */ - stw r2, GPR2_OFFSET(r1) - mflr r3 - stw r3, EXC_LR_OFFSET(r1) - bl 0f -0: /* - * r3 = exception vector entry point - * (256 * vector number) + few instructions - */ + stw r3, GPR3_OFFSET-EXCEPTION_FRAME_END(r1) mflr r3 - /* - * r3 = r3 >> 8 = vector + stw r3, EXC_LR_OFFSET-EXCEPTION_FRAME_END(r1) + bla push_normalized_frame + + /* IMPORTANT: prologue size MUST be < 32 bytes; 'altivec unavailable' exception + * is already at 0xf20 :-( */ - srwi r3,r3,8 - ba push_normalized_frame PUBLIC_VAR (default_exception_vector_code_prolog_size) + PUBLIC_VAR (tgpr_clr_exception_vector_code_prolog_size) - default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog + default_exception_vector_code_prolog_size = . - default_exception_vector_code_prolog + tgpr_clr_exception_vector_code_prolog_size= . - tgpr_clr_exception_vector_code_prolog .p2align 5 PUBLIC_VAR (push_normalized_frame) SYM (push_normalized_frame): + stwu r1, - (EXCEPTION_FRAME_END)(r1) + mfcr r3 + stw r3, EXC_CR_OFFSET(r1) + /* + * r3 = exception vector entry point + * (256 * vector number) + few instructions + */ + mflr r3 + /* + * r3 = r3 >> 8 = vector + */ + srwi r3,r3,8 stw r3, EXCEPTION_NUMBER_OFFSET(r1) stw r0, GPR0_OFFSET(r1) + /* R2 should never change (EABI: pointer to .sdata2) - we + * save it nevertheless.. + */ + stw r2, GPR2_OFFSET(r1) mfsrr0 r3 stw r3, SRR0_FRAME_OFFSET(r1) mfsrr1 r3 stw r3, SRR1_FRAME_OFFSET(r1) /* * Save general purpose registers - * Already saved in prolog : R1, R2, R3, LR. - * Saved a few line above : R0 + * Already saved in prolog : R1, R3, LR. + * Saved a few line above : R0, R2 * * Manual says that "stmw" instruction may be slower than * series of individual "stw" but who cares about performance @@ -79,8 +98,6 @@ SYM (push_normalized_frame): */ stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */ - mfcr r31 - stw r31, EXC_CR_OFFSET(r1) mfctr r30 stw r30, EXC_CTR_OFFSET(r1) mfxer r28 diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h index 4e5ce04d41..55823893ce 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h @@ -75,11 +75,13 @@ */ extern void default_exception_vector_code_prolog(); +extern void tgpr_clr_exception_vector_code_prolog(); /* This symbol is generated by the linker; prevent it from * being accessed in one of the short data areas by declaring * it as an array */ extern int default_exception_vector_code_prolog_size[]; +extern int tgpr_clr_exception_vector_code_prolog_size[]; /* codemove is like memmove, but it also gets the cache line size * as 4th parameter to synchronize them. If this last parameter is diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c b/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c index 873e1c08ca..75f57898c3 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c @@ -12,12 +12,15 @@ * * $Id$ */ +#include <rtems.h> +#include <bsp.h> + #include <rtems/bspIo.h> #include <bsp/vectors.h> #include <libcpu/raw_exception.h> #include <libcpu/spr.h> -#include <bsp.h> +#include <libcpu/cpuIdent.h> static rtems_raw_except_global_settings exception_config; static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; @@ -143,6 +146,7 @@ int mpc60x_vector_is_valid(rtems_vector vector); void initialize_exceptions() { int i; + int has_shadowed_gprs = 0; /* * Initialize pointer used by low level execption handling @@ -162,12 +166,27 @@ void initialize_exceptions() * is not a bug as it is defined a .set directly in asm... */ exception_config.defaultRawEntry.hdl.raw_hdl_size = (unsigned) default_exception_vector_code_prolog_size; + + switch ( get_ppc_cpu_type() ) { + case PPC_603e: + case PPC_8240: + has_shadowed_gprs = 1; + default: break; + } for (i=0; i <= exception_config.exceptSize; i++) { if (!mpc60x_vector_is_valid (i)) { continue; } exception_table[i].exceptIndex = i; - exception_table[i].hdl = exception_config.defaultRawEntry.hdl; + if ( has_shadowed_gprs + && ( ASM_IMISS_VECTOR == i + || ASM_DLMISS_VECTOR == i + || ASM_DSMISS_VECTOR == i ) ) { + exception_table[i].hdl.raw_hdl = tgpr_clr_exception_vector_code_prolog; + exception_table[i].hdl.raw_hdl_size = (unsigned)tgpr_clr_exception_vector_code_prolog_size; + } else { + exception_table[i].hdl = exception_config.defaultRawEntry.hdl; + } exception_table[i].hdl.vector = i; exception_table[i].on = nop_except_enable; exception_table[i].off = nop_except_enable; |