/************************************************************* * File: imon/mips.s * Purpose: startup code for IMON * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970225 Added disasm as offset 18. * 970305 Added get_rsa as offset 19. * 970311 Added gdbmode as offset 20. * 970409 Added addEnvRec as offset 21. * 980703 Removed cpuInit from offset 8 * 980703 Replaced hostInit(0) with cpuInit() * 980703 Added code to save cpuType after cpuInit is called. */ #include #define NEWMEMSIZE /* * If you are new to MIPS assembly language programming, you will find * the following texts useful: * * "MIPS Risc Architecture", by Jerry Kane, published by Prentice Hall, * ISBN 0-13-584749-4. * * "MIPS Programmer's Handbook", by Erin Farquhar and Philip Bunce, * published by Morgan Kaufmann, ISBN 1-55860-297-6. * */ .extern initial_sr,4 .text reset_exception: #ifdef LR64008 li t0,0xbff40400 li t1,0x1fc0 sh t1,(t0) .set noreorder nop nop nop nop nop .set reorder #endif la k0,_start or k0,K1BASE j k0 .align 8 utlb_miss_exception: la k0,_exception li k1,K1BASE or k0,k1 j k0 .align 7 general_exception: la k0,_exception li k1,K1BASE or k0,k1 j k0 .align 9 /************************************************************* * util_routines: * table of entry address used by clients to access IMON's * internal routines. It's the main reason that IMON must * be built with "-G 0" (no gp addressing). * This table starts at PROM base + 0x200 */ .globl util_routines util_routines: .word read # 0 .word write # 1 .word open # 2 .word close # 3 .word ioctl # 4 .word printf # 5 .word addRegRec # 6 .word malloc # 7 .word 0 # 8 This used to be cpuInit .word getMonEnv # 9 .word 0 # 10 .word flush_cache # 11 .word stop # 12 .word getBpid # 13 .word xvwmode # 14 .word gdbstop # 15 .word setTrcbp # 16 .word addCmdRec # 17 .word disasm # 18 970225 .word get_rsa # 19 970405 .word gdbmode # 20 970311 .word addEnvRec # 21 970409 .word 0:8 # spare #define STKSIZE 8192 .comm stack,STKSIZE /* IMON's own stack */ .comm hndlrtbl,16*4 .comm flush_ptr,4 .comm k1temp,4 /************************************************************* * _start: * This is the entry point of the entire PROM Monitor */ .globl _start .ent _start _start: # force kSeg1 in case control is passed here from Kseg0 la t0,1f or t0,K1BASE j t0 1: # set SR and CAUSE to something sensible li v0,SR_BEV .set noreorder .set noat mtc0 v0,C0_SR mtc0 zero,C0_CAUSE .set at .set reorder # Set up the CPU and enable the RAM. This routine figures out # what type of CPU this is and returns the address of the # cache flushing routine in s0. # It also returns the CPU type in s1. jal cpuInit # set up a K1seg stack la sp,stack+STKSIZE-24 or sp,K1BASE # flush the dcache li a0,DCACHEI or s0,K1BASE jal s0 li a0,FDATA jal cpdata jal clrbss #ifndef NON_CACHED # copy handler la a0,handler la a1,ehandler li a2,0x80000000 # utlb miss jal copyHandler #ifdef LR33000 li a2,0x80000040 # debug jal copyHandler #endif li a2,0x80000080 # general vector jal copyHandler #endif # flush the caches li a0,DCACHEI jal s0 li a0,ICACHEI jal s0 # ok to use k0seg stack now la sp,stack+STKSIZE-24 # save the flush routine ptr for later use sw s0,flush_ptr # save the CPU type for later use sw s1,cpuType /* * Provide address for use by shrc function. This feature * permits text to be placed in the PROM and to be read as a * sort of 'startup' file when IMON starts, it is normally * disabled because it can cause problems if the PROM has * junk in the end. */ #ifdef ENB_SHRC la a0,edata la t1,_fdata subu a0,t1 la t1,etext addu a0,t1 #endif la t0,imoninit # initialize IMON jal t0 # ints might be enabled from here on #ifndef NON_CACHED .set noreorder # clear BEV mfc0 v0,C0_SR nop li t0,~SR_BEV and v0,t0 mtc0 v0,C0_SR sw v0,initial_sr .set reorder #endif # # ######################################################### la t0,monmain jal t0 # transfer to main part of IMON j _start .end _start /************************************************************* * handler: * This is the handler that gets copied to the exception vector * addresses. */ .globl handler .ent handler handler: .set noat la k0,_exception j k0 ehandler: .set at .end handler /************************************************************* * _exit: * This is an exit routine, it should never be called except when IMON * is aborted while running under SABLE. */ .globl _exit .ent _exit _exit: #ifndef SABLE break 0 #endif j ra .end _exit /************************************************************* * _exception: * This routine is used to handle all exceptions. * o It handles an exceptions that may occur within IMON * (hopefully none). * o It checks to see if it's a reserved instr trap. If so, * go to the mult/div emulation routine. This is needed * for the LR4002/3. * o It checks to see if it's a floating-point exception * (if IMON has fp emulation enabled.) * o onintr is supported to permit measurements via time(). */ .globl _exception .ent _exception _exception: .set noat # need to save k1 some where (I assume). la k0,k1temp sw k1,(k0) # if (curlst == &pmlst) branch to exc2 la k0,curlst lw k0,(k0) la k1,pmlst beq k0,k1,exc2 # skip if in IMON # see if we have a user defined handler .set noreorder mfc0 k0,C0_CAUSE nop .set reorder and k0,CAUSE_EXCMASK la k1,hndlrtbl addu k0,k1 # calc table entry addr lw k0,(k0) # get contents of table entry beq k0,zero,exc2 lw k0,4(k0) # user routine addr la k1,k1temp lw k1,(k1) # restore k1 j k0 # jump to user handler exc2: #ifdef FPEM /* see if it's a cp1 unusable */ .set noreorder mfc0 k0,C0_CAUSE nop .set reorder li k1,(CAUSE_CEMASK|CAUSE_EXCMASK) and k0,k1 li k1,((1<