📄 k4001.s
字号:
j k0 # jump to client rfe .set reorder 1: # check for SENDSAP li k1,SENDSAP bne k1,v0,1f # It is SENDSAP. Send address of savearea. la a0,savearea or a0,1 # indicate new format bal put_word b ice_loop 1: # else. Not a special word. sw v0,(s0) # save word in instr_buffer addu s0,4 # ready for next word b ice_loop .end ice_loop .set at/************************************************************** get_cmd()* Get one word from the serial interface. The result goes* in v0.*/ .globl get_cmd .ent get_cmdget_cmd: li k1,UART_BASE li a1,4 # get 4 bytes # wait for rxrdy 3: lbu k0,UART_STATUS(k1) sll k0,UART_RXRDY bgez k0,3b # get the byte lbu k0,UART_RXHR(k1) # get the byte # first byte? bne a1,4,2f # brif not first byte # is the byte a wakeup? bne k0,ATTN,2f # brif not a wakeup # wait for txrdy 1: lbu k0,UART_STATUS(k1) sll k0,UART_TXRDY bgez k0,1b # send an ack li k0,ACK sb k0,UART_TXHR(k1) # put the byte b 3b 2: sll v0,8 # move word into position or v0,k0 # merge byte with word subu a1,1 # bytecount-- bne a1,zero,3b # do next byte j ra .end get_cmd/************************************************************** get_word()* Get one word from the serial interface. The result goes* in v0.*/ .globl get_word .ent get_wordget_word: li k1,UART_BASE li a1,4 # get 4 bytes # wait for rxrdy 1: lbu k0,UART_STATUS(k1) sll k0,UART_RXRDY bgez k0,1b lbu k0,UART_RXHR(k1) # get the byte sll v0,8 # move word into position or v0,k0 # merge byte with word subu a1,1 # bytecount-- bne a1,zero,1b # do next byte j ra .end get_word/************************************************************** put_word()* Put one word to the serial interface. The word to be sent* comes from a0.*/ .globl put_word .ent put_wordput_word: li k1,UART_BASE li a1,4 # put 4 bytes # wait for txrdy 1: lbu k0,UART_STATUS(k1) sll k0,UART_TXRDY bgez k0,1b sb a0,UART_TXHR(k1) # put the byte srl a0,8 # next byte subu a1,1 # bytecount-- bne a1,zero,1b # do next byte j ra .end put_word/************************************************************** End of interrupt-level code **************************************************************/ .set at/************************************************************** cpu_init()* This is where the CPU-specific init code lives.* This implementation is for the bdmr4001 (4001 eval board).* This example is designed to use ChanA of the DUART for connection* to the IceController.*/ .globl cpu_init .ent cpu_initcpu_init: # set M_CFG4001 # wben, ~tlben, ~dberr, pgsz=111, rdpri, cmode=00, dcen, is1en, icen # isize=int5,int4 dsize=int3,int2 li t0,(CFG_WBEN|CFG_DCEN|CFG_IS1EN|CFG_ICEN) #or t0,(CFG_PGSZ_2K|CFG_CMODE_NORM|CFG_DSNOOP|CFG_ISNOOP) or t0,(CFG_PGSZ_2K|CFG_CMODE_NORM) # setting of DBS0/1 and IBS0/1 is controlled by jumpers on the # board that are connected to the CpCond inputs. But rather than # use a whole bunch of bc1t instructions to test them. I connect # them to the interrupt inputs and then test the CAUSE register. # connect CpCond inputs to interrupt inputs or t0,(CFG_CPC0EN|CFG_CPC1EN|CFG_CPC2EN|CFG_CPC3EN) li t1,M_CFG4001 sw t0,(t1) # write CFG4001 lw zero,(t1) # flush wb .set noreorder # allow time for CFG change to take effect nop nop mfc0 t1,C0_CAUSE nop .set reorder and t2,t1,(CAUSE_INT5|CAUSE_INT4) srl t2,14-2 or t0,t2 and t2,t1,(CAUSE_INT3|CAUSE_INT2) srl t2,12-5 or t0,t2 li t1,M_CFG4001 sw t0,(t1) # disconnect cpCond inputs from interrupt inputs and t0,~(CFG_CPC0EN|CFG_CPC1EN|CFG_CPC2EN|CFG_CPC3EN) li t1,M_CFG4001 sw t0,(t1) # write CFG4001 lw zero,(t1) # flush wb#ifdef LR4001_RevA # RevA has a problem when accessing the timers. Use this # sequence for reliable operation. # set refresh timer (timer0) # 60MHz clock 16ms/1024 = 941 # Flush Write Buffer & Update config to turnoff I-caches .set noreorder li t0, 0xbfff0000 #Address of Configuration Register lw t1, (t0) #Determine ConfigReg value nop li t3, 0xfffffffc and t2, t1, t3 # Mask out Icache enables sw t2, (t0) #Store it back out lw zero, (t0) #Loading it 2nd time creates dependency nop #Along with this nop nop nop nop nop nop nop nop nop li a0,M_TMR4001 li a1,941 sw a1,O_TIC0(a0) # Actual sw to Timer. lw zero,O_TIC0(a0) # flush wb li a1,(TMODE_EN0|TMODE_PULSE0) sw a1,O_TMODE(a0) # write to tmode reg lw zero,O_TMODE(a0) # flush wb sw t1, (t0) # Return config register to original value. nop .set reorder#else # set refresh timer (timer0) # 60MHz clock 16ms/1024 = 941 li t1,M_TMR4001 li t0,941 sw t0,O_TIC0(t1) # set timer initial count li t0,(TMODE_EN0|TMODE_PULSE0) sw t0,O_TMODE(t1) # write to tmode reg lw zero,O_TMODE(t1) # flush wb#endif # initialize chan A of the DUART li t2,UART_BASE # 5 = 0 mask off all ints sb zero,5*4(t2) # 2 = 0a disable rx & tx li t0,0x0a sb t0,2*4(t2) # 2 = 10 reset MR reg li t0,0x10 sb t0,2*4(t2) # 2 = 20 reset rx li t0,0x20 sb t0,2*4(t2) # 2 = 30 reset tx li t0,0x30 sb t0,2*4(t2) # 0 = 13 no parity, 8 bits data li t0,0x13 sb t0,0*4(t2) # 0 = 0f 2 stop bits li t0,0x0f sb t0,0*4(t2) # 4 = ACR = 0 li t0,0 sb t0,4*4(t2) li t1,ACR_COPY sb t0,(t1) # 1 = cc 38400 li t0,0xcc sb t0,1*4(t2) sb zero,4*4(t2) # 2 = 05 enable rx & tx li t0,0x05 sb t0,2*4(t2) # 5 = 02 enable rx ints li t0,0x02 sb t0,5*4(t2) li t1,IMR_COPY sb t0,(t1) j ra .end cpu_init#ifdef RUN_APPLICATION#define RAM_GENVECT 0x80000080#define STACKSIZE (8*1024) .comm stack,STACKSIZE .comm flush_cache_ptr,4/**************************************************************/ .globl _exit .globl cstartup .ent cstartupcstartup: # identify CPU and flush both caches la s0,r4001_flush or s0,K1BASE li a0,ICACHEI jal s0 li a0,DCACHEI jal s0#if 1 /* necessary for ROM-resident code */ # copy the data to RAM li a0,FDATA jal cpdata#endif # note that clrbss must not use a3 jal clrbss # set the global data pointer la gp,_gp # save the address of the cache flush routine sw s0,flush_cache_ptr # set sp la sp,stack+STACKSIZE-24#if 1 /* use the RAM-resident exception vectors */ # copy exception handler to RAM vector la t1,ehandler la t2,ehandler_end li t3,RAM_GENVECT 1: lw t0,(t1) sw t0,(t3) addu t1,4 addu t3,4 bne t1,t2,1b # flush the Icache li a0,ICACHE jal flush_cache # clear BEV .set noreorder mfc0 t0,C0_SR nop and t0,~SR_BEV mtc0 t0,C0_SR .set reorder#endif # call the main C routine la t0,main jal t0_exit: b _exit .end cstartup/************************************************************** getmachtype()* Return the CPU type.*/ .globl getmachtype .ent getmachtypegetmachtype: li v0,4001 j ra .end getmachtype/************************************************************** ehandler:* This is the exception handler that gets copied to RAM.* If the application uses exceptions, it will use this* code to transfer control to the IceKernel for all * non-application exceptions.*/ .ent ehandlerehandler: la k0,gen_vector j k0ehandler_end: .end ehandler/************************************************************** flush_cache(type)* A C-callable routine to flush the caches.*/ .globl flush_cache .ent flush_cacheflush_cache: lw t0,flush_cache_ptr j t0 .end flush_cache#endif /* RUN_APPLICATION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -