📄 mips.s
字号:
/************************************************************* * 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 <imon.h>#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 .textreset_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 8utlb_miss_exception: la k0,_exception li k1,K1BASE or k0,k1 j k0 .align 7general_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_routinesutil_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 t01: # 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 handlerhandler: .set noat la k0,_exception j k0ehandler: .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 handlerexc2:#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<<CAUSE_CESHIFT)|(11<<CAUSE_EXCSHIFT)) subu k0,k1 bne k0,zero,1f la k0,cop1 # jump to emulation package la k1,k1temp lw k1,(k1) # restore k1 j k0 1:#endif#ifdef INCLUDE_MDEM /* see if it's a reserved instr trap */ .set noreorder mfc0 k0,C0_CAUSE nop .set reorder li k1,CAUSE_EXCMASK and k0,k1 li k1,(10<<CAUSE_EXCSHIFT) subu k0,k1 bne k0,zero,1f # save return address la k0,1f subu sp,8 sw k0,4(sp) la k0,trap10 # jump to emulation package la k1,k1temp lw k1,(k1) # restore k1 j k0 # save return address in k0 1:#endif .set noreorder mfc0 a0,C0_EPC nop mfc0 a1,C0_CAUSE nop .set reorder la k1,k1temp lw k1,(k1) # restore k1 j pmexception .set at .end _exception/************************************************************** onintr()* Used to install user defined exception handlers.*/ .globl onintr .ent onintronintr: # a0=exec a1=struct sll a0,2 la t0,idummy sw t0,(a1) la t1,hndlrtbl addu t1,a0 lw t0,(t1) beq t0,zero,1f sw t0,(a1)1: sw a1,(t1) j ra .end onintr/************************************************************** clrhndlrs()* Used to remove user defined exception handlers.* also recopies exception vector handler.*/ .globl clrhndlrs .ent clrhndlrsclrhndlrs: subu sp,24 sw ra,20(sp) # remove user defined handlers la t1,hndlrtbl li t2,0 li t3,161: sll t0,t2,2 addu t0,t1 sw zero,(t0) addu t2,1 bne t2,t3,1b#ifndef NON_CACHED # recopy the 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 li a0,ICACHE jal flush_cache#endif lw ra,20(sp) addu sp,24 j ra .end clrhndlrs/************************************************************** copyHandler:* Used to copy the exception handler to the various* vector addresses.*/ .globl copyHandler .ent copyHandlercopyHandler: # a0=src a1=end a2=dst # must not change a0 or a1 # must force a0 & a1 to kseg1 or t0,a0,K1BASE or t1,a1,K1BASE1: lw v0,(t0) sw v0,(a2) addu t0,4 addu a2,4 blt t0,t1,1b j ra .end copyHandler/************************************************************** flush_cache(type,adr)* Flush the designated cache (ICACHEI, DCACHE, ICACHE, IADDR)* Note that this is not a real subroutine, it simply* transfers control to the routine pointed to by 'flush_ptr',* being very careful to not use Kseg0 just in case the caches* haven't been flushed yet.*/ .globl flush_cache .ent flush_cacheflush_cache: # a0=type a1=adr la t1,flush_ptr or t1,K1BASE lw t0,(t1) or t0,K1BASE bne t0,zero,1f j ra 1: j t0 .end flush_cache#ifdef ATMIZER/************************************************************** atmizer_flush* dummy flush routine, the ATMizer has no flushable cache*/ .globl atmizer_flush .ent atmizer_flushatmizer_flush: j ra .end atmizer_flush#endif/* * This is used by onintr to terminate the list of user defined handlers * for a given EXC value. */ .dataidummy: .word 0 .word exc2/* provide a default value for a1 */ .datainitial_a1: .asciiz "g"#define TBLBASE 0x80020000#define TBLENTRY(n,m) \ .globl m; \ .ent m; \m: li t0,TBLBASE+(4*n); \ lw t0,(t0); \ j t0; \ .end m .textTBLENTRY(5,read_target)TBLENTRY(6,write_target)TBLENTRY(7,run_target)TBLENTRY(8,_setbp_target)TBLENTRY(9,_clrbp_target)TBLENTRY(10,_flush_target)/* 11 is unused */TBLENTRY(12,is_writeable_target)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -