/************************************************************************ * * start.sx * * Startup code for application. * ************************************************************************/ /************************************************************************ * Include files ************************************************************************/ #include "mips.h" /************************************************************************ * Definitions ************************************************************************/ #define PERIOD 0x100 #define STACK_SIZE 0x1000 /************************************************************************ * Public variables ************************************************************************/ /************************************************************************ * Static variables ************************************************************************/ .lcomm ARG, 0x10 /************************************************************************ * Implementation : Static functions ************************************************************************/ /************************************************************************ * Implementation : Public functions ************************************************************************/ /************************************************************************ * * _start * Description : * ------------- * * Function linked to application start address * * Initialises sp and gp registers and clears bss section * * Return values : * --------------- * * None * ************************************************************************/ .section ".text","ax" .globl _start .ent _start _start: .set noreorder /* Initialize some registers to get deterministic data trace. Probably that would lead to an error if we ould try to return to Yamon. */ move $16, $0 move $17, $0 move $18, $0 move $18, $0 move $19, $0 move $20, $0 move $21, $0 move $22, $0 move $23, $0 /* Setup sp and gp */ la $28, _gp la $29, _sp /* read out architecture revision from CP0 16 selection 0 */ // lw $11, MIPS_REL($5) mfc0 $11, $16, 0 li $8, 0x1C00 and $11, $8 beq $11, $0,_clear_bss /* Architecture revison 0: => No EBASE register! */ nop /* Handle sp and gp for multicore applications */ /* read out CPU core number from CP0 15.1: CPUNum = bits [9:0] */ mfc0 $11, $15, 1 li $8, 0x3FF and $11, $8 bne $11, $0, _generic /* not core 0 ? */ nop _clear_bss: /* Clear bss */ la $8, _fbss /* First address */ la $9, _end /* Last address */ addu $9, 3 li $10, ~3 and $9, $10 1: sw $0, 0($8) bne $8, $9, 1b addiu $8, 4 _generic: /* calculate and set core specific sp. */ move $8, $0 li $8, STACK_SIZE mul $8, $8, $11 /* calculate stack offset relative to stack base address */ sub $29, $8 /* calculate core instance specific stack start address */ /* Set Interupt vector base t0 0x80003000*/ mfc0 $8, $15, 1 ori $8, $8, 0x3000 mtc0 $8, $15, 1 /* clear BEV , ERL & IE in Status register */ mfc0 $8, $12 and $8, ~0x400005 /* Set IM7(Timer) in Status register */ or $8, 0x8000 mtc0 $8, $12 /* Clear Count Register and set Compare Register */ mtc0 $0, $9 lui $8, PERIOD mtc0 $8, $11 /* Setup argc and argv */ lui $4, 0 la $5, ARG /* read out configuration registers */ _readConfig_0: mfc0 $11, $16, 0 li $8, 0x1C00 and $8, $11 beq $8, $0,_setMipsRev /* Architecture revison 0: => No EBASE register! */ move $9, $0 li $9, 0x1 _setMipsRev: sw $9, MIPS_REL($5) addiu $4, $4, 1 /* check if config 1 is available */ li $8, 0x80000000 and $8, $11 beq $8, $0,_configReadOutEnd _readConfig_1: mfc0 $11, $16, 1 li $8, 0x4 and $8, $11 beq $8, $0,_setISA move $9, $0 li $9, MIPS16 _setISA: sw $9, ISA($5) addiu $4, $4, 1 li $8, 0x1 and $8, $11 beq $8, $0,_setFPU move $9, $0 li $9, 0x1 _setFPU: sw $9, FPU($5) addiu $4, $4, 1 /* check if config 2 is available */ li $8, 0x80000000 and $8, $11 beq $8, $0,_configReadOutEnd _readConfig_2: mfc0 $11, $16, 2 /* check if config 3 is available */ li $8, 0x80000000 and $8, $11 beq $8, $0,_configReadOutEnd _readConfig_3: mfc0 $11, $16, 3 li $8, 0x8000 and $8, $11 beq $8, $0,_setISA2 /*Micro Mips*/ lw $9, ISA($5) li $9, MICRO_MIPS _setISA2: sw $9, ISA($5) _configReadOutEnd: /* Get ready to jump to main */ move $16, $31 la $8, main /* Jump to main */ jal $8 nop b _exit .set reorder .end _start .section ".text","ax" .globl _exit .ent _exit _exit: .set noreorder b _exit .set reorder .end _exit /************************************************************************ * * __main, _gccmain * Description : * ------------- * * Dummy functions called by main() function. * * GNU-gcc 2.8.1 : main() calls __main * GNU-gcc 2.9 : main() calls __gccmain * * Return values : * --------------- * * None * ************************************************************************/ .set noreorder .globl __main .globl __gccmain .ent __main __main: __gccmain: jr $31 nop .end __main /************************************************************************ * * Description : _exception * ------------- * ************************************************************************/ .section ".excp","ax" .globl _exception .ent _exception .set noreorder _exception: /* increment PC by 4, because in case of an exception the EPC points to the location where the exception has been caused! */ mfc0 $25, $14 addi $25,$25, 4 mtc0 $25, $14 eret nop .end _exception .set reorder /************************************************************************ * * Description : _genexception * ------------- * ************************************************************************/ .section ".gen_excp","ax" .globl _genexception .ent _genexception .set noreorder _genexception: /* Clear Count Register and set Compare Register */ mtc0 $0, $9 lui $25, PERIOD mtc0 $25, $11 eret nop .end _genexception .set reorder