📄 cachevr4131alib.s
字号:
*/ .ent cacheVr4131DCFlushInvalidateFUNC_LABEL(cacheVr4131DCFlushInvalidate) move t0, a0 /* copy of virtAddr */ move t1, a1 /* copy of byte count */ /* flush range */ lw a2,cacheVr4131DCacheSize lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Writeback_D) /* invalidate */ move a0, t0 /* restore virtAddr */ move a1, t1 /* restore byte count */ lw a2,cacheVr4131DCacheSize lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D) j ra .end cacheVr4131DCFlushInvalidate/********************************************************************************* cacheVr4131DCInvalidateAll - invalidate entire R4000 data cache** RETURNS: N/A** void cacheVr4131DCInvalidateAll (void)*/ .ent cacheVr4131DCInvalidateAllFUNC_LABEL(cacheVr4131DCInvalidateAll) /* secondary cacheops do all the work if present */ lw a2,cacheVr4131SCacheSize blez a2,1f lw a3,cacheVr4131SCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD) b 99f1: lw a2,cacheVr4131DCacheSize blez a2, 99f lw a3,cacheVr4131DCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)99: j ra .end cacheVr4131DCInvalidateAll/********************************************************************************* cacheVr4131DCInvalidate - invalidate R4000 data cache locations** RETURNS: N/A** void cacheVr4131DCInvalidate* (* baseAddr, /@ virtual address @/* byteCount /@ number of bytes to invalidate @/* )*/ .ent cacheVr4131DCInvalidateFUNC_LABEL(cacheVr4131DCInvalidate) /* * This routine was originally written with a Hit_Writeback_Inv_D, * which did a flush/invalidate operation. NEC then informed WRS * that Hit_Writeback_Inv_D wasn't trustworthy on some CPU * silicon revision, so we should use separate Writeback and * Invalidate operations instead. * * Since NEC authorized standalone use of Invalidate, in theory * this code should be able to dispense with the flush portion * entirely. But, the 4131 cache has been _so_ sensitive, * that it's deemed not worth the risk to change the implementation * until the changed version can be _thoroughly_ tested. */ move t0, a0 /* backup of virtAddr */ move t1, a1 /* backup of byteCount */ /* flush */ lw a2,cacheVr4131DCacheSize lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Writeback_D) /* invalidate */ move a0, t0 /* restore virtAddr */ move a1, t1 /* restore byte count */ lw a2,cacheVr4131DCacheSize lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D) j ra .end cacheVr4131DCInvalidate/********************************************************************************* cacheVr4131ICInvalidateAll - invalidate entire R4000 instruction cache** RETURNS: N/A** void cacheVr4131ICInvalidateAll (void)*/ .ent cacheVr4131ICInvalidateAllFUNC_LABEL(cacheVr4131ICInvalidateAll) /* secondary cacheops do all the work if present */ lw a2,cacheVr4131SCacheSize blez a2,1f lw a3,cacheVr4131SCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD) b 98f1: lw a2,cacheVr4131ICacheSize blez a2,99f lw a3,cacheVr4131ICacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Invalidate_I)98: /* touch TLBHI register to clear the branch history buffer. This is */ /* required for (at a minimum) the NEC Vr4122. */ mfc0 a2, C0_TLBHI HAZARD_CP_READ mtc0 a2, C0_TLBHI HAZARD_TLB99: j ra .end cacheVr4131ICInvalidateAll/********************************************************************************* cacheVr4131ICInvalidate - invalidate R4000 data cache locations** RETURNS: N/A** void cacheVr4131ICInvalidate* (* baseAddr, /@ virtual address @/* byteCount /@ number of bytes to invalidate @/* )*/ .ent cacheVr4131ICInvalidateFUNC_LABEL(cacheVr4131ICInvalidate) /* secondary cacheops do all the work if present */ lw a2,cacheVr4131SCacheSize blez a2,1f lw a3,cacheVr4131SCacheLineSize move a1,a2 vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_SD) b 98f1: lw a2,cacheVr4131ICacheSize blez a2, 99f lw a3,cacheVr4131ICacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_I) 98: /* touch TLBHI register to clear the branch history buffer. This is */ /* required for (at a minimum) the NEC Vr4122. */ mfc0 a2, C0_TLBHI HAZARD_CP_READ mtc0 a2, C0_TLBHI HAZARD_TLB99: j ra .end cacheVr4131ICInvalidate/******************************************************************************** cacheVr4131VirtPageFlush - flush one page of virtual addresses from caches** Change ASID, flush the appropriate cache lines from the D- and I-cache,* and restore the original ASID.** CAVEAT: This routine and the routines it calls MAY be running to clear* cache for an ASID which is only partially mapped by the MMU. For that* reason, the caller may want to lock interrupts.** RETURNS: N/A** void cacheVr4131VirtPageFlush (UINT asid, void *vAddr, UINT pageSize);*/ .ent cacheVr4131VirtPageFlushFUNC_LABEL(cacheVr4131VirtPageFlush) /* Save parameters */ move t4,a0 /* ASID to flush */ move t0,a1 /* beginning VA */ move t1,a2 /* length */ /* * When we change ASIDs, our stack might get unmapped, * so use the stack now to free up some registers for use: * t0 - virtual base address of page to flush * t1 - page size * t2 - original SR * t3 - original ASID * t4 - ASID to flush */ /* lock interrupts */ mfc0 t2, C0_SR HAZARD_CP_READ li t3, ~SR_INT_ENABLE and t3, t2 mtc0 t3, C0_SR HAZARD_INTERRUPT /* change the current ASID to context where page is mapped */ mfc0 t3, C0_TLBHI /* read current TLBHI */ HAZARD_CP_READ and t3, 0xff /* extract ASID field */ beq t3, t4, 0f /* branch if no need to change */ mtc0 t4, C0_TLBHI /* Store new EntryHi */ HAZARD_TLB0: /* clear the virtual addresses from D- and I-caches */ lw a2,cacheVr4131DCacheSize blez a2,1f move a0, t0 move a1, t1 lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Writeback_D) move a0, t0 move a1, t1 lw a2,cacheVr4131DCacheSize lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D)1: lw a2,cacheVr4131ICacheSize blez a2,1f /* Invalidate primary instruction cache */ move a0,t0 move a1,t1 lw a3,cacheVr4131ICacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)1: /* restore the original ASID */ mtc0 t3, C0_TLBHI /* Restore old EntryHi */ HAZARD_TLB mtc0 t2, C0_SR /* restore interrupts */ j ra .end cacheVr4131VirtPageFlush/******************************************************************************** cacheVr4131Sync - sync region of memory through all caches** RETURNS: N/A** void cacheVr4131Sync (void *vAddr, UINT pageSize);*/ .ent cacheVr4131SyncFUNC_LABEL(cacheVr4131Sync) /* Save parameters */ move t0,a0 /* beginning VA */ move t1,a1 /* length */ /* lock interrupts */ mfc0 t2, C0_SR HAZARD_CP_READ li t3, ~SR_INT_ENABLE and t3, t2 mtc0 t3, C0_SR HAZARD_INTERRUPT /* * starting with primary caches, push the memory * block out completely */ sync lw a2,cacheVr4131ICacheSize blez a2,1f /* Invalidate primary instruction cache */ move a0,t0 move a1,t1 lw a3,cacheVr4131ICacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)1: lw a2,cacheVr4131DCacheSize blez a2,1f /* Flush primary data cache */ move a0, t0 move a1, t1 lw a3,cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Writeback_D) /* Invalidate primary data cache */ move a0, t0 move a1, t1 lw a2, cacheVr4131DCacheSize lw a3, cacheVr4131DCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D) 1: lw a2,cacheVr4131SCacheSize blez a2,1f /* Invalidate secondary cache */ mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI HAZARD_CACHE_TAG move a0,t0 move a1,t1 lw a3,cacheVr4131SCacheLineSize icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)1: mtc0 t2, C0_SR /* restore interrupts */ j ra .end cacheVr4131Sync
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -