📄 cachesh7750alib.s
字号:
and r4,r0 /* r0: ca & 0xfffffc00 */ mov.l r0,@r1 /* purge cache entry associatively */ bra II_Loop_Index; add #ICACHE_LINE_SIZE,r4 /* ca += ICACHE_LINE_SIZE */II_Exit: nop; nop; nop; nop /* secure 8 insns before rts */ nop; nop; nop; nop /* XXX these 4 nops may not necessary */ rts; mov #0,r0 /* return OK */ .align 2II_XF0000008: .long 0xf0000008 /* associative purge region */II_XFF00001C: .long 0xff00001c /* CCR address in P4 */II_XFC00: .word 0xfc00II_X1FE0: .word 0x1fe0 /* comparison done in each way */II_XFE0: .word 0xfe0/******************************************************************************** cacheSh7750ILineInvalOp - invalidate a I-cache entry with MMU enabled** This routine invalidates an instruction cache entry for a specified virtual* address. Note that an associative I-cache invalidation results in nop if* the specified address mishits I-TLB. This routine refills I-TLB before* invalidating I-cache so that it always success invalidating an instruction* cache entry even if MMU is enabled. This routine has to be executed on P2.** STATUS cacheSh7750ILineInval (void *va) /@ virtual address to invalidate @/* {* UINT32 ie, ue, lrui;* UINT32 key = excBlock (); /@ BLOCK EXCEP (SR.BL=1) @/* UINT32 asid = *(UINT32 *)0xff000000 & 0xff; /@ PTEH.ASID (for AE) @/* UINT32 mmucr = *(UINT32 *)0xff000010; /@ MMUCR @/** /@ once invalidate U-TLB and I-TLB associatively (set D,~V) @/** *(UINT32 *)0xf6000080 = ((UINT32)va & 0xfffffc00) | 0x200 | asid;** /@ reload U-TLB @/** if (mmuStub (va) != OK) /@ mmuStub() without rte @/* {* excUnblock (key); /@ UNBLOCK EXCEPTION @/* return ERROR;* }** ue = (mmucr >> 2) & 0x00003f00; /@ extract MMUCR.URC @/** /@ figure out the Least Recently Used I-TLB entry @/** lrui = mmucr >> 26; /@ extract MMUCR.LRUI @/** if ((lrui & 0x38) == 0x38) ie = 0x000; /@ simulate LRU algoritm @/* else if ((lrui & 0x26) == 0x06) ie = 0x100;* else if ((lrui & 0x15) == 0x01) ie = 0x200;* else if ((lrui & 0x0b) == 0x00) ie = 0x300;* else* {* excUnblock (key); /@ UNBLOCK EXCEPTION @/* return ERROR; /@ this should not happen @/* }** /@ copy just loaded U-TLB entry (PTEH/PTEL/PTEA) to I-TLB @/** *(UINT32 *)(0xf2000000 | ie) = *(UINT32 *)(0xf6000000 | ue); /@ pteh @/* *(UINT32 *)(0xf3000000 | ie) = *(UINT32 *)(0xf7000000 | ue); /@ ptel @/* *(UINT32 *)(0xf3800000 | ie) = *(UINT32 *)(0xf7800000 | ue); /@ ptea @/** /@ invalidate I-cache associatively (set ~V, I-TLB hit assured) @/** if (*CCR & CCR_IC_INDEX_ENABLE)* *(UINT32 *)(0xf0000008 | ((UINT32)va & 0xfe0) |* ((va & 0x2000000) >> 13)) = (UINT32)va & 0xfffffc00;* else* *(UINT32 *)(0xf0000008 | ((UINT32)va & 0x1fe0))* = (UINT32)va & 0xfffffc00;** excUnblock (key); /@ UNBLOCK EXCEPTION @/* return OK;* }** RETURNS: OK, or ERROR** NOMANUAL*/ .type _cacheSh7750ILineInvalOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750ILineInvalOp: /* r4: va */ mov.l IL_X10000000,r0; /* r0: SR.BL bit */ stc sr,r7 /* r7: old sr */ or r7,r0 ldc r0,sr /* BLOCK INTERRUPT/EXCEPTION */ mov.l IL_MmuRegsBase,r3; /* r3: 0xff000000 */ mov #0xfc,r1 mov r4,r6 shll8 r1 /* r1: 0xfffffc00 */ mov.l @(PTEH,r3),r0; and r1,r6 /* r6: va & 0xfffffc00 */ and #0xff,r0 /* r0: PTEH.ASID */ or r6,r0 /* r0: (va & 0xfffffc00) | ASID */ mov.l r0,@(PTEH,r3) /* update PTEH */ mov #2,r1 shll8 r1 /* r1: 0x200 (UTLB: D, ~V) */ mov.l IL_XF6000080,r2; /* r2: U-TLB address array with A-bit */ or r1,r0 /* r0: (va & 0xfffffc00)|0x200|ASID */ mov.l r0,@r2 /* once invalidate U-TLB and I-TLB */ mov #-10,r0 mov r6,r1 /* r1:ABCDEFGHIJKLMNOPQRSTUV0000000000*/ shld r0,r1 /* r1:0000000000ABCDEFGHIJKLMNOPQRSTUV*/ mov.w IL_X0FFC,r2; /* r2:00000000000000000000111111111100*/ mov #-12,r0 and r1,r2 /* r2:00000000000000000000KLMNOPQRST00*/ shld r0,r1 /* r1:0000000000000000000000ABCDEFGHIJ*/ mov.l @(TTB,r3),r0; shll2 r1 /* r1:00000000000000000000ABCDEFGHIJ00*/ mov.l @(r0,r1),r0; /* r0: --> PTELs table */ cmp/eq #-1,r0 bt IL_Err mov.l @(r0,r2),r1; /* r1: PTEL entry to load */ swap.b r1,r0 tst #0x01,r0 /* invalid if PTEL.V (bit8) is zero */ bt IL_Err mov.l r1,@(PTEL,r3) /* update PTEL */ ldtlb /* load PTEH/PTEL/PTEA to U-TLB */ mov.l @(MMUCR,r3),r1; /* extract URC and LRUI from MMUCR */ shlr2 r1 swap.b r1,r0 and #0x3f,r0 /* r0: MMUCR.URC */ swap.b r0,r2 /* r2: U-TLB entry specifier */ mov #-24,r0 shld r0,r1 /* r1: MMUCR.LRUI */ mov r1,r0 /* simulate I-TLB LRU algorithm */ and #0x38,r0 cmp/eq #0x38,r0 bt.s IL_LoadItlb0 /* if ((LRUI & 0x38)==0x38) ie=0x000; */ mov r1,r0 and #0x26,r0 cmp/eq #0x06,r0 bt.s IL_LoadItlb1 /* if ((LRUI & 0x26)==0x06) ie=0x100; */ mov r1,r0 and #0x15,r0 cmp/eq #0x01,r0 bt.s IL_LoadItlb2 /* if ((LRUI & 0x15)==0x01) ie=0x200; */ mov r1,r0 tst #0x0b,r0 bt.s IL_LoadItlb /* if ((LRUI & 0x0b)==0x00) ie=0x300; */ mov #3,r3IL_Err: bra IL_Exit; /* else */ mov #-1,r0 /* return ERROR;*/IL_X0FFC: .word 0x0ffc .align 2IL_X10000000: .long 0x10000000IL_MmuRegsBase: .long MMU_REGS_BASEIL_XF6000080: .long 0xf6000080IL_LoadItlb0: bra IL_LoadItlb; mov #0,r3IL_LoadItlb1: bra IL_LoadItlb; mov #1,r3IL_LoadItlb2: mov #2,r3IL_LoadItlb: /* r2: U-TLB entry specifier */ shll8 r3 /* r3: I-TLB entry specifier */ /* r4: va */ /* r6: va & 0xfffffc00 */ mov.l IL_XF6000000,r0; mov.l @(r0,r2),r1; /* copy UTLB.PTEH */ mov.l IL_XF2000000,r0; mov.l r1,@(r0,r3); /* load ITLB.PTEH */ mov.l IL_XF7000000,r0; mov.l @(r0,r2),r1; /* copy UTLB.PTEL */ mov.l IL_XF3000000,r0; mov.l r1,@(r0,r3); /* load ITLB.PTEL */ mov.l IL_XF7800000,r0; mov.l @(r0,r2),r1; /* copy UTLB.PTEA */ mov.l IL_XF3800000,r0; mov.l r1,@(r0,r3); /* load ITLB.PTEA */ mov.l IL_XFF00001C,r1 /* r1: CCR address */ mov.l @r1,r1 /* r1: CCR value */ mov #0x80,r0 extu.b r0,r0 shll8 r0 /* r0: CCR_IC_INDEX_ENABLE */ tst r0,r1 /* check CCR_IC_INDEX_ENABLE bit */ bt IL_No_Index_Mode /* if off, go to IL_No_Index_Mode */ mov.w IL_XFE0,r1; mov #0x20,r0 shll16 r0 shll8 r0 /* r0: 0x02000000 */ tst r0,r4 /* check A25 bit */ bt.s IL_A25_Off /* if off, keep A12 bit off */ and r1,r4 /* r4: va & 0xfe0 */ mov.l IL_XF0001008,r0; /* if on, enable A12 bit */ bra IL_Inval or r0,r4 /* r4: 0xf0001008 | (va & 0xfe0) */IL_No_Index_Mode: mov.w IL_X1FE0,r1; and r1,r4 /* r4: va & 0x1fe0 */IL_A25_Off: mov.l IL_XF0000008,r0; or r0,r4 /* r4: 0xf0000008 | (va & 0xxfe0) */IL_Inval: mov.l r6,@r4 /* invalidate I-cache associatively */ nop /* secure 8 insn before leaving P2 */ nop nop nop nop nop mov #0,r0 /* return OK */IL_Exit: ldc r7,sr /* UNBLOCK INTERRUPT/EXCEPTION */ rts; nopIL_XFE0: .word 0xfe0IL_X1FE0: .word 0x1fe0 .align 2IL_XF6000000: .long 0xf6000000 /* U-TLB address array */IL_XF7000000: .long 0xf7000000 /* U-TLB data array 1 */IL_XF7800000: .long 0xf7800000 /* U-TLB data array 2 */IL_XF2000000: .long 0xf2000000 /* I-TLB address array */IL_XF3000000: .long 0xf3000000 /* I-TLB data array 1 */IL_XF3800000: .long 0xf3800000 /* I-TLB data array 2 */IL_XFF00001C: .long 0xff00001c /* CCR address in P4 */IL_XF0000008: .long 0xf0000008 /* I-cache address array with A-bit */IL_XF0001008: .long 0xf0001008 /* I-cache address array with A-bit and A25-bit *//******************************************************************************** cacheSh7750TInvalOp - clear V bit of cache tag** NOMANUAL*/ .type _cacheSh7750TInvalOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750TInvalOp: bra TC_Init; mov #0xfe,r3 /* r3: 0xfffffffe ~V *//******************************************************************************** cacheSh7750TFlushOp - clear U bit of cache tag** NOMANUAL*/ .type _cacheSh7750TFlushOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750TFlushOp: bra TC_Init; mov #0xfd,r3 /* r3: 0xfffffffd ~U *//******************************************************************************** cacheSh7750TClearOp - clear U & V bits of cache tag** This routine blocks interrupts to assure an atomic read-modify-write* of cache tag, thus it must be executed on P2 region.** STATUS cacheSh7750TClearOp (UINT32 *pt, int ix, UINT32 from, UINT32 to)* {* UINT32 tag;** SR |= BL; /@ BLOCK INTERRUPTS @/** tag = *pt; /@ read cache tag @/** if (tag & (TAG_USED | TAG_VALID))* {* if (ix < 0) /@ force invalidating cache tag @/* {* *pt = tag & ~(TAG_USED | TAG_VALID); /@ modify cache tag @/* }* else /@ check cached address @/* {* UINT32 ca = (tag & 0xfffffc00) | (ix & 0x3ff);** if (ca >= from && ca <= to)* *pt = tag & ~(TAG_USED | TAG_VALID); /@ modify cache tag @/* }* }** SR &= ~BL; /@ UNBLOCK INTERRUPTS @/** return OK;* }** NOMANUAL*/ .type _cacheSh7750TClearOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750TClearOp: mov #0xfc,r3 /* r3: 0xfffffffc ~(U|V) */TC_Init: /* r4: &tag, r5: ix, r6: from, r7: to */ mov.l r8,@-sp mov.l TC_X10000000,r0; stc sr,r8 /* r8: original SR */ or r8,r0 ldc r0,sr /* BLOCK INTERRUPTS */ mov.l @r4,r0 /* r0: cache tag */ tst #0x01,r0 /* TAG_VALID? */ bt TC_Done cmp/pz r5 /* ix >= 0 ? */ bf TC_Purge mov.l TC_XFFFFFC00,r1 and r0,r1 /* r1: tag & 0xfffffc00 */ mov.w TC_X03FF,r2 and r5,r2 /* r2: ix & 0x3ff */ or r2,r1 /* r1: ca (cached address) */ cmp/hs r6,r1 /* ca_begin <= ca ? */ bf TC_Done cmp/hs r1,r7 /* ca <= ca_end ? */ bf TC_DoneTC_Purge: and r3,r0 /* clear U & V */ mov.l r0,@r4 /* purge cache entry */ nop; nop; nop; nop /* secure 8 insns before rts */ nop; nop; nop; nopTC_Done: ldc r8,sr /* UNBLOCK INTERRUPTS */ mov.l @sp+,r8 rts; mov #0,r0 /* return OK */ .align 2TC_X10000000: .long 0x10000000 /* SR.BL */TC_XFFFFFC00: .long 0xfffffc00TC_X03FF: .word 0x03ff/******************************************************************************** cacheSh7750DFlush - flush some entries from SH7750 D-cache** STATUS cacheSh7750DFlush (void *from, size_t bytes);* {* UINT32 ca, ca_nop;** if (bytes == 0) return OK;** ca = (UINT32)from & 0xffffffe0;* ca_nop = (UINT32)from + bytes;** while (ca < ca_nop)* {* ocbwb (ca);** ca += 32;* }* return OK;* }** RETURNS: OK, always.** NOMANUAL*/ .type _cacheSh7750DFlush,@function .align _ALIGN_TEXT_cacheSh7750DFlush: tst r5,r5 /* if (bytes == 0) */ bt OCFend /* return OK; */ mov #0xe0,r0 /* r0: 0xffffffe0 */ and r4,r0 /* r0 -> (current cache line) */ add r4,r5 /* r5 -> (last adrs to flush) + 1 */OCFlp: cmp/hs r5,r0 /* if (r5 <= r0) */ bt OCFend /* return OK; */ ocbwb @r0 /* write back, no invalidation */ bra OCFlp; add #32,r0 /* r0 -> (next cache line) */OCFend: rts; mov #0,r0 /* return OK *//******************************************************************************** cacheSh7750DInvalidate - invalidate some entries from SH7750 D-cache** STATUS cacheSh7750DInvalidate (void *from, size_t bytes);** RETURNS: OK, always.** NOMANUAL*/ .type _cacheSh7750DInvalidate,@function .align _ALIGN_TEXT_cacheSh7750DInvalidate: tst r5,r5 /* if (bytes == 0) */ bt OCIend /* return; */ mov #0xe0,r0 /* r0: 0xffffffe0 */ and r4,r0 /* r0 -> (current cache line) */ add r4,r5 /* r5 -> (last adrs to invalidate) + 1 */OCIlp: cmp/hs r5,r0 /* if (r5 <= r0) */ bt OCIend /* return; */ ocbi @r0 /* invalidate, no write-back */ bra OCIlp; add #32,r0 /* r0 -> (next cache line) */OCIend: rts; mov #0,r0 /* return OK *//******************************************************************************** cacheSh7750DClear - clear some entries from SH7750 operand(data) cache** STATUS cacheSh7750DClear (void *from, size_t bytes);** RETURNS: OK, always.** NOMANUAL*/ .type _cacheSh7750DClear,@function .align _ALIGN_TEXT_cacheSh7750DClear: tst r5,r5 /* if (bytes == 0) */ bt OCCend /* return; */ mov #0xe0,r0 /* r0: 0xffffffe0 */ and r4,r0 /* r0 -> (current cache line) */ add r4,r5 /* r5 -> (last adrs to clear) + 1 */OCClp: cmp/hs r5,r0 /* if (r5 <= r0) */ bt OCCend /* return; */ ocbp @r0 /* write-back, then invalidate */ bra OCClp; add #32,r0 /* r0 -> (next cache line) */OCCend: rts; mov #0,r0 /* return OK *//******************************************************************************** cacheSh7750PipeFlush - flush write buffers to memory** This routine forces the processor output buffers to write their contents* to RAM. A cache flush may have forced its data into the write buffers,* then the buffers need to be flushed to RAM to maintain coherency.** RETURNS: OK.** NOMANUAL*/ .type _cacheSh7750PipeFlush,@function .align _ALIGN_TEXT_cacheSh7750PipeFlush: mov.l PF_XA0000000,r1 mov #0,r0 /* return OK */ rts; mov.l @r1,r1 /* flush write-buffer by P2 read */ .align 2PF_XA0000000: .long 0xa0000000 /* P2 (reset vector) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -