diff --git a/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog b/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog index 2254ca5167..14b1c7feb3 100644 --- a/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog +++ b/c/src/lib/libbsp/powerpc/mvme3100/ChangeLog @@ -1,3 +1,13 @@ +2007-03-05 Till Straumann + + * start/start.S, startup/bspstart.c: disable memory-select + errors early (in start.S) to avoid hangs due to speculative + memory access (motload maps absent memory in TLBs). + Remove TLB mappings for which no physical memory is installed + (bspstart). Enable HID1[RFXE] so that 'core_fault_in' errors + result in a machine-check rather than stalling the machine. + Re-enable memory-select errors at this point. + 2007-03-05 Till Straumann * Makefile.am: add e500/mmu.rel to libbsp_a_LIBADD. diff --git a/c/src/lib/libbsp/powerpc/mvme3100/start/start.S b/c/src/lib/libbsp/powerpc/mvme3100/start/start.S index cab9261c0a..485a00483d 100644 --- a/c/src/lib/libbsp/powerpc/mvme3100/start/start.S +++ b/c/src/lib/libbsp/powerpc/mvme3100/start/start.S @@ -25,6 +25,13 @@ #define KERNELBASE 0x0 +/* cannot include from assembly :-( */ +#ifndef BSP_8540_CCSR_BASE +#define BSP_8540_CCSR_BASE 0xe1000000 +#endif + +#define ERR_DISABLE_REG (BSP_8540_CCSR_BASE + 0x2e44) + .text .globl __rtems_entry_point .type __rtems_entry_point,@function @@ -34,6 +41,25 @@ __rtems_entry_point: mr r29,r5 mr r28,r6 mr r27,r7 + /* disable checking for memory-select errors; motload has all TLBs + * mapping a possible larger area as memory (not-guarded, caching-enabled) + * than actual physical memory is available. + * In case of speculative loads this may cause 'memory-select' errors + * which seem to raise 'core_fault_in' (found no description in + * the manual but I experienced this problem). + * Such errors (if HID1[RFXE] is clear) may *stall* execution + * leading to mysterious 'hangs'. + * Note: enabling HID1[RFXE] at this point makes no sense since + * exceptions are not configured yet. Therefore we disable + * memory-select errors. + * Eventually (bspstart.c) we want to delete TLB entries for + * which no physical memory is present. + */ + lis r3, ERR_DISABLE_REG@ha + lwz r4, ERR_DISABLE_REG@l(r3) + /* disable memory-select errors */ + ori r4, r4, 1 + stw r4, ERR_DISABLE_REG@l(r3) /* Use MotLoad's TLB setup for now; caches are on already */ bl __eabi /* setup EABI and SYSV environment */ diff --git a/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c index c5486abf34..9451062680 100644 --- a/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,8 @@ #define SHOW_MORE_INIT_SETTINGS #undef DEBUG +#define NumberOf(arr) (sizeof(arr)/sizeof(arr[0])) + #ifdef DEBUG #define STATIC #else @@ -234,13 +237,15 @@ SPR_RW(HID1) void bsp_start( void ) { -unsigned char *stack; -register uint32_t intrStack; -register uint32_t *intrStackPtr; -unsigned char *work_space_start; -char *chpt; -ppc_cpu_id_t myCpu; -ppc_cpu_revision_t myCpuRevision; +unsigned char *stack; +register uint32_t intrStack; +register uint32_t *intrStackPtr; +unsigned char *work_space_start; +char *chpt; +ppc_cpu_id_t myCpu; +ppc_cpu_revision_t myCpuRevision; +int i; +E500_tlb_va_cache_t *tlb; VpdBufRec vpdData [] = { { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 }, @@ -321,13 +326,45 @@ VpdBufRec vpdData [] = { printk("Going to start PCI buses scanning and initialization\n"); #endif + BSP_mem_size = BSP_get_mem_size(); + { - /* disable checking for memory-select errors */ - *(volatile uint32_t*)0xe1002e44 |= 1; - /* clear all pending errors */ - *(volatile uint32_t*)0xe1002e40 = 0xffffffff; + /* memory-select errors were disabled in 'start.S'; + * motload has all TLBs mapping a possible larger area as + * memory (not-guarded, caching-enabled) than actual physical + * memory is available. + * In case of speculative loads this may cause 'memory-select' errors + * which seem to raise 'core_fault_in' (found no description in + * the manual but I experienced this problem). + * Such errors (if HID1[RFXE] is clear) may *stall* execution + * leading to mysterious 'hangs'. + * + * Here we remove all mappings, re-enable memory-select + * errors and make sure we enable HID1[RFXE] to avoid + * stalls (since we don't implement handling individual + * error-handling interrupts). + */ + /* enable machine check for bad bus errors */ _write_HID1( _read_HID1() | 0x20000 ); + + rtems_e500_initlb(); + + for ( i=0, tlb=rtems_e500_tlb_va_cache; iatt.v + && 0xa != (tlb->att.wimge & 0xa) + && (tlb->va.va_epn<<12) >= BSP_mem_size ) { + rtems_e500_clrtlb( E500_SELTLB_1 | i ); + } + } + + /* clear all pending memory errors */ + _ccsr_wr32(0x2e40, 0xffffffff); + /* enable checking for memory-select errors */ + _ccsr_wr32(0x2e44, _ccsr_rd32(0x2e44) & ~1 ); } printk("Build Date: %s\n",BSP_build_date); @@ -389,8 +426,6 @@ VpdBufRec vpdData [] = { _write_SPRG0(PPC_BSP_HAS_FIXED_PR288); #endif - BSP_mem_size = BSP_get_mem_size(); - if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) { char *endp; uint32_t sz;