📄 a4001.s
字号:
/************************************************************* * File: lib/a4001.s * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history */#ifndef LR4001#define LR4001#endif#include <mips.h> .globl a4001init .ent a4001inita4001init: beq a0,zero,1f j c4001init 1: # 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) # 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 .set noreorder # set refresh timer (timer0) # 60MHz clock 16ms/1024 = 941 # Flush Write Buffer & Update config to turnoff I-caches 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. li a1,(TMODE_EN0|TMODE_PULSE0) lw a1,O_TMODE(a0) # flush wb 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) li t0,(TMODE_EN0|TMODE_PULSE0) sw t0,O_TMODE(t1) lw zero,O_TMODE(t1) # flush wb#endif # enable int0 for berr signals .set noreorder mfc0 t0,C0_SR nop or t0,(SR_IBIT3|SR_IEC) mtc0 t0,C0_SR nop # give it time... nop nop .set reorder # select the correct cache flushing routines la s0,r4001_flush j ra .end a4001init#ifdef LR4001_RevA/* pjb 10/28/95 Modified to add 8 nops */ .set noreorder/************************************************************** swtmr4001(addr,value)* Software fix for XC bug, which manifests itself as a PCI* transaction that begins during phase2 of bclk. * This bum transaction occurs when the transaction immediately * preceeding it is a cpu read or write to the timer, that also* starts on a falling bclk edge. Since the timer operates at* the same frequency as the CPU, it is okay, but confuses the* following transaction to the XC.** The following code ensures that transactions to the timer start* during phase1 of the bclk, by :* 1) Changing Cacheconfig to turn off I-caches.* 2) flushing the write buffer, * 3) Perform timer transaction.* 4) Return Cacheconfig to original value.* t0:config reg address,t1:original config setting,* t2:modified config setting.*/ .globl swtmr4001 .ent swtmr4001swtmr4001: # Flush Write Buffer & Update config to turnoff I-caches 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 # 8 more nops in case a cache line fill nop # was scheduled before the dependancy nop # forced the cfg reg write to disable nop # the icache. nop # even though the caches are disabled nop # the cache line fill fetch has to continue nop # to completion. Making the now non-cached nop # intructions available to the cpu as they # are burst fetched off the bus. # # We think. sw a1, (a0) # Actual sw to Timer. sw t1, (t0) # Return config register to original value. nop j ra # jump back to caller, return from subroutine nop .end swtmr4001/************************************************************** lwtmr4001(addr)* Software fix for XC bug. See description for swtimer routine.* t0:config reg address,t1:original config setting,* t2:modified config setting.* value returned in v0*/ .globl lwtmr4001 .ent lwtmr4001lwtmr4001: # Flush Write Buffer & Update config to turnoff I-caches li t0, 0xbfff0000 #Address of Configuration Register lw t1, (t0) #Determine ConfigReg value nop #t1 holds original config setting. 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 # 8 more nops in case a cache line fill nop # was scheduled before the dependancy nop # forced the cfg reg write to disable nop # the icache. nop # even though the caches are disabled nop # the cache line fill fetch has to continue nop # to completion. Making the now non-cached nop # intructions available to the cpu as they # are burst fetched off the bus. lw v0, (a0) # Actual lw from Timer. sw t1, (t0) # Return config register to original value. nop j ra # jump back to caller, return from subroutine nop .set reorder .end lwtmr4001#endif /* LR4001_RevA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -