diff options
Diffstat (limited to '')
7 files changed, 159 insertions, 14 deletions
diff --git a/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h b/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h index 215d608d6f..2c54a016dc 100644 --- a/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h +++ b/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h @@ -48,8 +48,7 @@ extern "C" { #define TMS570_POM_REGADDRMASK ((1<<23)-1) - -int mem_dump(void *buf, unsigned long start, unsigned long len, int blen); +void tms570_initialize_and_clear(void); void tms570_pom_remap(void); /** @} */ diff --git a/c/src/lib/libbsp/arm/tms570/irq/irq.c b/c/src/lib/libbsp/arm/tms570/irq/irq.c index 2e6e3db637..7a2a55fff5 100644 --- a/c/src/lib/libbsp/arm/tms570/irq/irq.c +++ b/c/src/lib/libbsp/arm/tms570/irq/irq.c @@ -201,6 +201,29 @@ rtems_status_code bsp_interrupt_facility_initialize(void) * can be provided by VIM hardware */ sctlr &= ~(1 << 24); + #if 0 + /* + * Option to enable exception table bypass for interrupts + * + * Because RTEMS requires all interrupts to be serviced through + * common _ARMV4_Exception_interrupt handler to allow task switching + * on exit from interrupt working correctly, vim_vec cannot point + * directly to individual vector handlers and need to point + * to single entry path. But if TMS570_VIM.IRQINDEX is then used + * to target execution to corresponding service then for some + * peripherals (i.e. EMAC) interrupt is already acknowledged + * by VIM and IRQINDEX is read as zero which leads to spurious + * interrupt and peripheral not serviced/blocked. + * + * To analyze this behavior we used trampolines which setup + * bsp_interrupt_vector_inject and pass execution to + * _ARMV4_Exception_interrupt. It works but is more ugly than + * use of POM remap for these cases where application does not + * start at address 0x00000000. If RTEMS image is placed at + * memory space beginning then no of these constructs is necessary. + */ + sctlr |= 1 << 24; + #endif asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr)); return RTEMS_SUCCESSFUL; diff --git a/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c b/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c index 749dd9d76f..6de64fe0f5 100644 --- a/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c +++ b/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c @@ -22,8 +22,61 @@ #include <stdint.h> #include <bsp/tms570-pom.h> #include <bsp/linker-symbols.h> +#include <rtems/score/armv4.h> #include <bsp.h> +/* + * Placement of exceptions target addresses in memory + * when insructions with opcode 0xe59ff018 + * ldr pc, [pc, #0x18] + * are used to fill ARM exception vectors area + */ +typedef struct{ + uint32_t reserved1; + uint32_t except_addr_undef; + uint32_t except_addr_swi; + uint32_t except_addr_prefetch; + uint32_t except_addr_abort; + uint32_t reserved2; + uint32_t except_addr_irq; + uint32_t except_addr_fiq; +}vec_remap_table; + +void bsp_block_on_exception(void); + +void bsp_block_on_exception(void){ + while(1); +} + +extern char bsp_int_vec_overlay_start[]; + +/* + * Global overlay target address holds shared MSB bits for all regions + * It is set to linker RAM_INT_VEC region - i.e. area reserved + * at internal SRAM memory start, address 0x08000000 + */ +uint32_t pom_global_overlay_target_address_start = + (uintptr_t)bsp_int_vec_overlay_start; + +/** + * @brief initialize and clear parameters overlay module (POM) + * + * clears all remap regions. The actual POM enable is left to the first user. + * + * @retval Void + */ +void tms570_initialize_and_clear(void) +{ + int i; + + TMS570_POM.GLBCTRL = 0 | (TMS570_POM_GLBCTRL_OTADDR(~0) & + pom_global_overlay_target_address_start); + + for ( i = 0; i < TMS570_POM_REGIONS; ++i ) { + TMS570_POM.REG[i].REGSIZE = TMS570_POM_REGSIZE_SIZE(TMS570_POM_REGSIZE_DISABLED); + } +} + /** * @brief remaps vector table * @@ -33,22 +86,50 @@ */ void tms570_pom_remap(void) { - int i; - uint32_t vec_overlay_start = 0x08000000; - uint32_t temp = 0; + uint32_t vec_overlay_start = pom_global_overlay_target_address_start; + /* + * Copy RTEMS the first level exception processing code + * to RAM area which can be used for later as POM overlay + * of Flash vectors. The code is expected to have for of eight + * ldr pc, [pc,#0x18] + * instructions followed by eight words with actual exception + * service routines target addresses. This is case of RTEMS default + * table found in + * c/src/lib/libbsp/arm/shared/start/start.S + */ memcpy((void*)vec_overlay_start, bsp_start_vector_table_begin, 64); - TMS570_POM.GLBCTRL = 0; - - for ( i = 0; i < TMS570_POM_REGIONS; ++i ) { - TMS570_POM.REG[i].REGSIZE = TMS570_POM_REGSIZE_SIZE(TMS570_POM_REGSIZE_DISABLED); + #if 0 + { + /* Fill exception table by catch error infinite loop for debugging */ + vec_remap_table* vec_table = (vec_remap_table*)(vec_overlay_start+32); + vec_table->except_addr_undef = (uint32_t)bsp_block_on_exception; + vec_table->except_addr_swi = (uint32_t)bsp_block_on_exception; + vec_table->except_addr_prefetch = (uint32_t)bsp_block_on_exception;//_ARMV4_Exception_prefetch_abort; + vec_table->except_addr_abort = (uint32_t)bsp_block_on_exception;//_ARMV4_Exception_data_abort; + vec_table->except_addr_irq = (uint32_t)_ARMV4_Exception_interrupt; + vec_table->except_addr_fiq = (uint32_t)bsp_block_on_exception;//_ARMV4_Exception_interrupt; } + #endif - TMS570_POM.REG[0].PROGSTART = TMS570_POM_PROGSTART_STARTADDRESS(0); + /* + * The overlay vectors replacement area cannot be used directly + * to replace jump instructions on start of Flash because instruction + * fetch through POM is not reliable supported (works in most times + * but sometimes fails). + * Area of 64 bytes starting at address 0x00000040 is replaced. + * This way target addresses are placed between 0x00000060 + * and 0x0000007F. If boot loader startup code contains instructions + * ldr pc,[pc,#0x58] + * (opcode 0xe59ff058) then the jump target addresses are replaced + * by pointers to actual RTEMS exceptions service functions. + */ + TMS570_POM.REG[0].PROGSTART = TMS570_POM_PROGSTART_STARTADDRESS(64); TMS570_POM.REG[0].OVLSTART = TMS570_POM_OVLSTART_STARTADDRESS(vec_overlay_start); TMS570_POM.REG[0].REGSIZE = TMS570_POM_REGSIZE_SIZE(TMS570_POM_REGSIZE_64B); TMS570_POM.GLBCTRL = TMS570_POM_GLBCTRL_ON_OFF(0xa) | TMS570_POM_GLBCTRL_ETO(0xa) | - (TMS570_POM_GLBCTRL_OTADDR(~0) & vec_overlay_start); + (TMS570_POM_GLBCTRL_OTADDR(~0) & + pom_global_overlay_target_address_start); } diff --git a/c/src/lib/libbsp/arm/tms570/startup/bspstart.c b/c/src/lib/libbsp/arm/tms570/startup/bspstart.c index 31ad1e7cc7..b7e2b62591 100644 --- a/c/src/lib/libbsp/arm/tms570/startup/bspstart.c +++ b/c/src/lib/libbsp/arm/tms570/startup/bspstart.c @@ -27,13 +27,49 @@ #include <bsp/irq-generic.h> #include <bsp/start.h> #include <bsp/bootcard.h> +#include <bsp/linker-symbols.h> +#include <rtems/endian.h> void bsp_start( void ) { - /* set the cpu mode to supervisor and big endian */ - arm_cpu_mode = 0x213; + #if BYTE_ORDER == BIG_ENDIAN + /* + * If CPU is big endian (TMS570 family variant) + * set the CPU mode to supervisor and big endian. + * Do not set mode if CPU is little endian + * (RM48 family variant) for which default mode 0x13 + * defined in cpukit/score/cpu/arm/cpu.c + * is right. + */ + arm_cpu_mode = 0x213; + #endif - tms570_pom_remap(); + tms570_initialize_and_clear(); + + /* + * If RTEMS image does not start at address 0x00000000 + * then first level exception table at memory begin has + * to be replaced to point to RTEMS handlers addresses. + * + * There is no VBAR or other option because Cortex-R + * does provides only fixed address 0x00000000 for exceptions + * (0xFFFF0000-0xFFFF001C alternative SCTLR.V = 1 cannot + * be used because target area corersponds to PMM peripheral + * registers on TMS570). + * + * Alternative is to use jumps over SRAM based trampolines + * but that is not compatible with + * Check TCRAM1 ECC error detection logic + * which intentionally introduces data abort during startup + * to check SRAM and if exception processing goes through + * SRAM then it leads to CPU error halt. + * + * So use of POM to replace jumps to vectors target + * addresses seems to be the best option. + */ + if ( (uintptr_t)bsp_start_vector_table_begin != 0 ) { + tms570_pom_remap(); + } /* Interrupts */ bsp_interrupt_initialize(); diff --git a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk index 0cdc783019..a32562fc6b 100644 --- a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk +++ b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk @@ -27,4 +27,6 @@ REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024; bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align); +bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC); + INCLUDE linkcmds.armv4 diff --git a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_intram b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_intram index c33dd6cdda..7cb683de3d 100644 --- a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_intram +++ b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_intram @@ -27,4 +27,6 @@ REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024; bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align); +bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC); + INCLUDE linkcmds.armv4 diff --git a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_sdram b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_sdram index 17039f1604..0117410467 100644 --- a/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_sdram +++ b/c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_sdram @@ -27,4 +27,6 @@ REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_EXT); bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024; bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align); +bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC); + INCLUDE linkcmds.armv4 |