diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/motorola_powerpc/vectors')
4 files changed, 429 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/Makefile.in b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/Makefile.in new file mode 100644 index 0000000000..c5175cde3f --- /dev/null +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/Makefile.in @@ -0,0 +1,64 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@:@srcdir@/../console: +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +INSTALL = @INSTALL@ + +PGM=${ARCH}/vectors.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=vectors_init +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES=$(srcdir)/vectors.h + +# Assembly source names, if any, go here -- minus the .s +S_PIECES=vectors +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(S_O_FILES) $(C_O_FILES) $(CC_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +preinstall: + $(MKDIR) $(PROJECT_INCLUDE)/bsp + $(INSTALL_CHANGE) -m 444 $(H_FILES) $(PROJECT_INCLUDE)/bsp + +all: ${ARCH} $(SRCS) preinstall $(OBJS) $(PGM) + + diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.S b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.S new file mode 100644 index 0000000000..7fe6a82f73 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.S @@ -0,0 +1,142 @@ +/* + * (c) 1999, Eric Valette valette@crf.canon.fr + * + * + * This file contains the assembly code for the PowerPC + * exception veneers for RTEMS. + * + * $Id$ + */ + + + +#include <bsp/vectors.h> +#include <libcpu/cpu.h> +#include <rtems/score/targopts.h> +#include "asm.h" + + +#define SYNC \ + sync; \ + isync + + PUBLIC_VAR (__rtems_start) + .section .entry_point_section,"awx",@progbits +/* + * Entry point information used by bootloader code + */ +SYM (__rtems_start): + .long __rtems_entry_point + + /* + * end of special Entry point section + */ + .text + .p2align 5 + +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) + stw r2, GPR2_OFFSET(r1) + mflr r2 + stw r2, EXC_LR_OFFSET(r1) + bl 0f +0: /* + * r3 = exception vector entry point + * (256 * vector number) + few instructions + */ + mflr r3 + /* + * r3 = r3 >> 8 = vector + */ + srwi r3,r3,8 + ba push_normalized_frame + + PUBLIC_VAR (default_exception_vector_code_prolog_size) + + default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog + + .p2align 5 +PUBLIC_VAR (push_normalized_frame) +SYM (push_normalized_frame): + stw r3, EXCEPTION_NUMBER_OFFSET(r1) + stw r0, GPR0_OFFSET(r1) + mfsrr0 r2 + stw r2, 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 + * + * Manual says that "stmw" instruction may be slower than + * series of individual "stw" but who cares about performance + * for the DEFAULT exception handler? + */ + 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 + stw r28, EXC_XER_OFFSET(r1) + /* + * Enable data and instruction address translation, exception nesting + */ + mfmsr r3 + ori r3,r3, MSR_RI | MSR_IR | MSR_DR + mtmsr r3 + SYNC + + /* + * Call C exception handler + */ + addi r3, r1, 0x8 + bl C_exception_handler + /* + * Restore registers status + */ + lwz r31, EXC_CR_OFFSET(r1) + mtcr r31 + lwz r30, EXC_CTR_OFFSET(r1) + mtctr r30 + lwz r29, EXC_LR_OFFSET(r1) + mtlr r29 + lwz r28, EXC_XER_OFFSET(r1) + mtxer r28 + + lmw r4, GPR4_OFFSET(r1) + lwz r2, GPR2_OFFSET(r1) + lwz r0, GPR0_OFFSET(r1) + + /* + * Disable data and instruction translation. Make path non recoverable... + */ + mfmsr r3 + xori r3, r3, MSR_RI | MSR_IR | MSR_DR + mtmsr r3 + SYNC + /* + * Restore rfi related settings + */ + + lwz r3, SRR1_FRAME_OFFSET(r1) + mtsrr1 r3 + lwz r3, SRR0_FRAME_OFFSET(r1) + mtsrr0 r3 + + lwz r3, GPR3_OFFSET(r1) + addi r1,r1, EXCEPTION_FRAME_END + SYNC + rfi + + + + + diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.h b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.h new file mode 100644 index 0000000000..2613ec9b43 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors.h @@ -0,0 +1,123 @@ +#ifndef LIBBSP_POWERPC_MCP750_VECTORS_H +#define LIBBSP_POWERPC_MCP750_VECTORS_H + +/* + * The callee (high level exception code written in C) + * will store the Link Registers (return address) at entry r1 + 4 !!!. + * So let room for it!!!. + */ +#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4 +#define SRR0_FRAME_OFFSET 8 +#define SRR1_FRAME_OFFSET 12 +#define EXCEPTION_NUMBER_OFFSET 16 +#define GPR0_OFFSET 20 +#define GPR1_OFFSET 24 +#define GPR2_OFFSET 28 +#define GPR3_OFFSET 32 +#define GPR4_OFFSET 36 +#define GPR5_OFFSET 40 +#define GPR6_OFFSET 44 +#define GPR7_OFFSET 48 +#define GPR8_OFFSET 52 +#define GPR9_OFFSET 56 +#define GPR10_OFFSET 60 +#define GPR11_OFFSET 64 +#define GPR12_OFFSET 68 +#define GPR13_OFFSET 72 +#define GPR14_OFFSET 76 +#define GPR15_OFFSET 80 +#define GPR16_OFFSET 84 +#define GPR17_OFFSET 88 +#define GPR18_OFFSET 92 +#define GPR19_OFFSET 96 +#define GPR20_OFFSET 100 +#define GPR21_OFFSET 104 +#define GPR22_OFFSET 108 +#define GPR23_OFFSET 112 +#define GPR24_OFFSET 116 +#define GPR25_OFFSET 120 +#define GPR26_OFFSET 124 +#define GPR27_OFFSET 128 +#define GPR28_OFFSET 132 +#define GPR29_OFFSET 136 +#define GPR30_OFFSET 140 +#define GPR31_OFFSET 144 +#define EXC_CR_OFFSET 148 +#define EXC_CTR_OFFSET 152 +#define EXC_XER_OFFSET 156 +#define EXC_LR_OFFSET 160 +#define EXC_DAR_OFFSET 164 +/* + * maintain the EABI requested 8 bytes aligment + * As SVR4 ABI requires 16, make it 16 (as some + * exception may need more registers to be processed...) + */ +#define EXCEPTION_FRAME_END 176 + +#ifndef ASM +/* + * default raw exception handlers + */ + +extern void default_exception_vector_code_prolog(); +extern int default_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 + * zero, it performs more or less like memmove. No copy is performed if + * source and destination addresses are equal. However the caches + * are synchronized. Note that the size is always rounded up to the + * next mutiple of 4. + */ +extern void * codemove(void *, const void *, unsigned int, unsigned long); +extern void initialize_exceptions(); + +typedef struct { + unsigned EXC_SRR0; + unsigned EXC_SRR1; + unsigned _EXC_number; + unsigned GPR0; + unsigned GPR1; + unsigned GPR2; + unsigned GPR3; + unsigned GPR4; + unsigned GPR5; + unsigned GPR6; + unsigned GPR7; + unsigned GPR8; + unsigned GPR9; + unsigned GPR10; + unsigned GPR11; + unsigned GPR12; + unsigned GPR13; + unsigned GPR14; + unsigned GPR15; + unsigned GPR16; + unsigned GPR17; + unsigned GPR18; + unsigned GPR19; + unsigned GPR20; + unsigned GPR21; + unsigned GPR22; + unsigned GPR23; + unsigned GPR24; + unsigned GPR25; + unsigned GPR26; + unsigned GPR27; + unsigned GPR28; + unsigned GPR29; + unsigned GPR30; + unsigned GPR31; + unsigned EXC_CR; + unsigned EXC_CTR; + unsigned EXC_XER; + unsigned EXC_LR; + unsigned EXC_MSR; + unsigned EXC_DAR; +} exception_frame; + +extern void C_exception_handler(exception_frame* excPtr); + +#endif /* ASM */ + +#endif /* LIBBSP_POWERPC_MCP750_VECTORS_H */ diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors_init.c b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors_init.c new file mode 100644 index 0000000000..9efc708e4e --- /dev/null +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/vectors/vectors_init.c @@ -0,0 +1,100 @@ +/* + * + */ +#include <bsp/vectors.h> +#include <libcpu/raw_exception.h> + +static rtems_raw_except_global_settings exception_config; +static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; + +void C_exception_handler(exception_frame* excPtr) +{ + int recoverable = 0; + + printk("exception handler called for exception %d\n", excPtr->_EXC_number); + printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0); + printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1); + printk("\t R0 = %x\n", excPtr->GPR0); + printk("\t R1 = %x\n", excPtr->GPR1); + printk("\t R2 = %x\n", excPtr->GPR2); + printk("\t R3 = %x\n", excPtr->GPR3); + printk("\t R4 = %x\n", excPtr->GPR4); + printk("\t R5 = %x\n", excPtr->GPR5); + printk("\t R6 = %x\n", excPtr->GPR6); + printk("\t R7 = %x\n", excPtr->GPR7); + printk("\t R8 = %x\n", excPtr->GPR8); + printk("\t R9 = %x\n", excPtr->GPR9); + printk("\t R10 = %x\n", excPtr->GPR10); + printk("\t R11 = %x\n", excPtr->GPR11); + printk("\t R12 = %x\n", excPtr->GPR12); + printk("\t R13 = %x\n", excPtr->GPR13); + printk("\t R14 = %x\n", excPtr->GPR14); + printk("\t R15 = %x\n", excPtr->GPR15); + printk("\t R16 = %x\n", excPtr->GPR16); + printk("\t R17 = %x\n", excPtr->GPR17); + printk("\t R18 = %x\n", excPtr->GPR18); + printk("\t R19 = %x\n", excPtr->GPR19); + printk("\t R20 = %x\n", excPtr->GPR20); + printk("\t R21 = %x\n", excPtr->GPR21); + printk("\t R22 = %x\n", excPtr->GPR22); + printk("\t R23 = %x\n", excPtr->GPR23); + printk("\t R24 = %x\n", excPtr->GPR24); + printk("\t R25 = %x\n", excPtr->GPR25); + printk("\t R26 = %x\n", excPtr->GPR26); + printk("\t R27 = %x\n", excPtr->GPR27); + printk("\t R28 = %x\n", excPtr->GPR28); + printk("\t R29 = %x\n", excPtr->GPR29); + printk("\t R30 = %x\n", excPtr->GPR30); + printk("\t R31 = %x\n", excPtr->GPR31); + printk("\t CR = %x\n", excPtr->EXC_CR); + printk("\t CTR = %x\n", excPtr->EXC_CTR); + printk("\t XER = %x\n", excPtr->EXC_XER); + printk("\t LR = %x\n", excPtr->EXC_LR); + printk("\t MSR = %x\n", excPtr->EXC_MSR); + if ( (excPtr->_EXC_number == ASM_DEC_VECTOR) || + (excPtr->_EXC_number == ASM_SYS_VECTOR) + ) + recoverable = 1; + if (!recoverable) BSP_panic("unrecoverable exception!!! Push reset button\n"); +} + +void nop_except_enable(const rtems_raw_except_connect_data* ptr) +{ +} +int except_always_enabled(const rtems_raw_except_connect_data* ptr) +{ + return 1; +} + +void initialize_exceptions() +{ + int i; + + exception_config.exceptSize = LAST_VALID_EXC + 1; + exception_config.rawExceptHdlTbl = &exception_table[0]; + exception_config.defaultRawEntry.exceptIndex = 0; + exception_config.defaultRawEntry.hdl.vector = 0; + exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_vector_code_prolog; + /* + * Note that next line the '&' before default_exception_vector_code_prolog_size + * 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; + for (i=0; i <= exception_config.exceptSize; i++) { + if (!mpc750_vector_is_valid (i)) { + continue; + } + exception_table[i].exceptIndex = i; + 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; + exception_table[i].isOn = except_always_enabled; + } + if (!mpc60x_init_exceptions(&exception_config)) { + BSP_panic("Exception handling initialization failed\n"); + } + else { + printk("Exception handling initialization done\n"); + } +} |