📄 cachesh7750alib.s
字号:
/* cacheSh7750ALib.s - HITACHI SH7750 cache management assembly function *//* Copyright 1998-2002 Wind River Systems, Inc. */ .data .global _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01l,18nov02,h_k fixed for IC index mode (SPR #81126).01k,20nov01,hk added cacheSh7750ILineInvalOp().01j,03oct01,frf modified cacheSh7750TClearOp() function, way information not necessary. Modified cacheSh7750IInvalOp() function, ass. purge by comparison in each way (enhanced mode).01i,06jun01,frf added 2way enhanced mode for SH7751R support.01h,04mar01,hk secure 8 insns before rts after modifying cache tag. fix tag mask to 0xfffffc00 (was 0x1ffffc00) in cacheSh7750IInvalOp.01g,06dec00,hk fixed ocbwb machine code (was 0x00d3). also changed ocbi/ocbp to use mnemonics. added misc cache tag control functions.01f,27mar00,hk added .type directive to function names.01e,17mar00,zl made use of alignment macro _ALIGN_TEXT01d,24feb99,hk fixed copyright year.01c,09oct98,hk code review: added NULL check. merged conditional branches.01b,20sep98,hk code review: deleted cacheSh7750CCRWrite.01a,24aug98,st written.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#define _ALIGN_UNCACHED_TEXT 2#define CCR_OC_RAM_ENABLE 0x20 /* CCR.ORA */#define CCR_OC_INVALIDATE 0x08 /* CCR.OCI */#define CCR_WRITE_BACK_P1 0x04 /* set P1 to copy-back */#define CCR_WRITE_THRU 0x02 /* set P0/P3 to write-thru */#define CCR_OC_ENABLE 0x01 /* enable operand cache */#define DCACHE_LINE_SIZE 32#define ICACHE_LINE_SIZE 32#define MMU_REGS_BASE 0xff000000#define PTEH 0x00 /* 0xff000000: Page Table Entry High */#define PTEL 0x04 /* 0xff000004: Page Table Entry Low */#define TTB 0x08 /* 0xff000008: Translation Table Base */#define MMUCR 0x10 /* 0xff000010: MMU Control Register */ .text .global _cacheSh7750CCRSetOp .global _cacheSh7750CCRGet .global _cacheSh7750DCacheOnOp .global _cacheSh7750DFlushAllOp .global _cacheSh7750DClearAllOp .global _cacheSh7750IInvalOp .global _cacheSh7750ILineInvalOp .global _cacheSh7750TInvalOp .global _cacheSh7750TFlushOp .global _cacheSh7750TClearOp .global _cacheSh7750DFlush .global _cacheSh7750DInvalidate .global _cacheSh7750DClear .global _cacheSh7750PipeFlush/******************************************************************************** cacheSh7750CCRSetOp - set cache control register to a specified value** This routine modifies CCR, thus it must be executed on P2 region.** UINT32 cacheSh7750CCRSetOp (UINT32 ccr)* {* *CCR = ccr;** return *CCR;* }** NOMANUAL*/ .type _cacheSh7750CCRSetOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750CCRSetOp: mov.l CS_XFF00001C,r1 mov.l r4,@r1 /* set CCR */ nop; nop; nop; nop /* secure 8 insns before rts */ nop; nop; nop; nop rts; mov.l @r1,r0 /* return CCR */ .align 2CS_XFF00001C: .long 0xff00001c /* CCR address in P4 *//******************************************************************************** cacheSh7750CCRGet - get cache control register value** This routine may be executed on any region.** UINT32 cacheSh7750CCRGet (void)* {* return *CCR;* }** NOMANUAL*/ .type _cacheSh7750CCRGet,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750CCRGet: mov.l CG_XFF00001C,r1 rts; mov.l @r1,r0 .align 2CG_XFF00001C: .long 0xff00001c /* CCR address in P4 *//******************************************************************************** cacheSh7750DCacheOnOp - turn on/off cache controller** This routine modifies CCR, thus it must be executed on P2 region.** STATUS cacheSh7750DCacheOnOp (BOOL on)* {* UINT32 ccr = *CCR;* BOOL enabled = ccr & CCR_OC_ENABLE;** if (enabled == on)* return ERROR;** SR |= BL; /@ BLOCK INTERRUPTS @/** if ((ccr & CCR_OC_ENABLE) &&* ((ccr & (CCR_WRITE_BACK_P1 | CCR_WRITE_THRU) != CCR_WRITE_THRU) ||* (*MMUCR & AT)))* {* cacheSh7750DClearAll ();* cacheSh7750PipeFlush ();* }** *CCR = ccr & ~CCR_OC_ENABLE; /@ disable D-cache @/** *CCR = ccr | CCR_OC_INVALIDATE; /@ invalidate entire D-cache @/** if (on == TRUE)* *CCR = ccr | CCR_OC_ENABLE; /@ enable D-cache @/** SR &= ~BL; /@ UNBLOCK INTERRUPTS @/** return OK;* }** NOMANUAL*/ .type _cacheSh7750DCacheOnOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750DCacheOnOp: mov.l r8,@-sp mov.l r9,@-sp mov.l r10,@-sp sts.l pr,@-sp bsr _cacheSh7750CCRGet; mov r4,r8 /* r8: on */ mov r0,r9 /* r9: original CCR */ tst #CCR_OC_ENABLE,r0 movt r0 /* 1: disabled, 0: enabled */ tst r8,r8 movt r1 /* 1: disable, 0: enable */ cmp/eq r0,r1 bt.s DO_Exit; /* keep current CCR.OCE */ mov #-1,r3 /* r3: ERROR */ mov.l DO_X10000000,r0; stc sr,r10 /* r10: original SR */ or r10,r0 ldc r0,sr /* BLOCK INTERRUPTS */ mov r9,r0 tst #CCR_OC_ENABLE,r0 bt DO_FlushDone /* CE: 0 (D-cache is disabled) */ and #(CCR_WRITE_BACK_P1 | CCR_WRITE_THRU),r0 cmp/eq #CCR_WRITE_THRU,r0 bf DO_Flush /* CB: 0, WT: 1 (no copyback region) */ mov.l DO_XFF000010,r1 mov.l @r1,r0 /* r0: MMUCR */ tst #0x1,r0 /* if (MMUCR.AT == 0) */ bt DO_FlushDone /* skip flushing */DO_Flush: bsr _cacheSh7750DClearAllOp; nop /* flush & invalidate entire D-cache */ bsr _cacheSh7750PipeFlush; nop /* flush write-back buffer by P2-read */DO_FlushDone: mov #(~CCR_OC_ENABLE),r4 bsr _cacheSh7750CCRSetOp; and r9,r4 /* disable D-cache */ or #CCR_OC_INVALIDATE,r0 bsr _cacheSh7750CCRSetOp; mov r0,r4 /* invalidate entire D-cache tags */ tst r8,r8 bt.s DO_Unblock; mov #0,r3 /* r3: OK */ or #CCR_OC_ENABLE,r0 bsr _cacheSh7750CCRSetOp; mov r0,r4 /* enable D-cache */DO_Unblock: ldc r10,sr /* UNBLOCK INTERRUPTS */DO_Exit: lds.l @sp+,pr mov.l @sp+,r10 mov.l @sp+,r9 mov.l @sp+,r8 rts; mov r3,r0 /* return status */ .align 2DO_X10000000: .long 0x10000000 /* SR.BL */DO_XFF000010: .long 0xff000010 /* MMUCR *//******************************************************************************** cacheSh7750DFlushAllOp - flush entire D-cache tags** STATUS cacheSh7750DFlushAllOp ()** NOMANUAL*/ .type _cacheSh7750DFlushAllOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750DFlushAllOp: bra DC_Init; mov #0xfd,r4/******************************************************************************** cacheSh7750DClearAllOp - clear entire D-cache tags** STATUS cacheSh7750DClearAllOp ()* {* int ix;* insigned int iway = 0; * unsigned int nMaxWay = 0; /@ only one way @/* unsigned int nMaxEntry = 128; ** SR |= BL; /@ BLOCK INTERRUPTS @/** /@ Enhanced mode ? @/ * if (ccr & CCR_2WAY_EMODE)* {* nMaxEntry = 256;** /@ The enhanced mode with half cache enabled reserves the * @ entire sencond way for RAM space and the first way entries still* @ remain for cache. Therefore with full cache mode, increase* @ the max number of way to 2.* @/* * if ((ccr & CCR_OC_RAM_ENABLE) == 0) * nMaxWay = 1; /@ two ways @/* } ** for (iway = nMaxWay << 14; iway >= 0; iway -= 0x4000)* {* /@ 0-127 or 0-255 in enhanced mode @/* for (ix = 0; ix <= nMaxEntry; ix += 0x20)* *(UINT32 *)(0xf4000000 | iway | ix) &= 0xfffffffc; ** /@ 255-383 or 255-511 in enhanced mode @/* for (ix = 0; ix <= nMaxEntry; ix += 0x20)* *(UINT32 *)(0xf4002000 | iway | ix) &= 0xfffffffc; ** /@ if not in RAM mode, only for compatible way @/* if ((ccr & CCR_OC_RAM_ENABLE == 0) * && (ccr & CCR_2WAY_EMODE) == 0))* {* /@ 128-255 @/* for (ix = 0; ix <= 0xfe0; ix += 0x20)* *(UINT32 *)(0xf4001000 | iway | ix) &= 0xfffffffc;* /@ 384-511 @/* for (ix = 0; ix <= 0xfe0; ix += 0x20)* *(UINT32 *)(0xf4003000 | iway | ix) &= 0xfffffffc; * }* }** SR &= ~BL; /@ UNBLOCK INTERRUPTS @/** return OK;* }** NOMANUAL*/ .type _cacheSh7750DClearAllOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750DClearAllOp: mov #0xfc,r4DC_Init: mov.l DC_X10000000,r0; stc sr,r7 /* r7: original SR */ or r7,r0 ldc r0,sr /* BLOCK INTERRUPTS */ mov.w DC_X2000,r6 /* r6: 0x2000 */ mov.w DC_128,r3 mov #0,r5 /* nMaxWay = 0 */ mov.l DC_XFF00001C,r1 mov.l @r1,r0 /* r0: ccr */ mov.l DC_X80000000,r1 tst r1,r0 /* if ( ccr & CCR_2WAY_EMODE ) */ bt DC_WayLoop /* ...no EMode, go to DC_NoEMode */ shll r3 /* r3: 256 */ tst #CCR_OC_RAM_ENABLE,r0 /* if (ccr & CCR_OC_RAM_ENABLE) */ bf DC_WayLoop /* with RAM mode only one way */ nop mov #1,r5 /* nMaxWay = 1 */ DC_WayLoop: shll16 r5 shlr2 r5 mov.l DC_XF4000000,r0 /* r0: 0xf4000000 */ or r5,r0 /* r0: 0xf4000000 | iway */DC_Loop: /* flush 0-127 or 0-255 */ /* flush 256-383 or 256-511 */ mov.l @r0,r1; mov.l @(r0,r6),r2 and r4,r1; and r4,r2 mov.l r1,@r0; mov.l r2,@(r0,r6) add #DCACHE_LINE_SIZE,r0 dt r3 bf DC_Loop mov.l DC_XFF00001C,r1 mov.l @r1,r0 /* r0: ccr */ tst #CCR_OC_RAM_ENABLE,r0 bf DC_NextWay mov.l DC_X80000000,r1 mov.w DC_128,r3 tst r1,r0 /* if ( ccr & CCR_2WAY_EMODE ) */ bf/s DC_NextWay /* EMode? go to the next way */ shll r3 /* r3: 256 */ mov.l DC_XF4001000,r0 /* r0: 0xf4001000 */DC_Loop2: /* flush 128-255 */ /* flush 384-511 */ mov.l @r0,r1; mov.l @(r0,r6),r2 and r4,r1; and r4,r2 mov.l r1,@r0; mov.l r2,@(r0,r6) add #DCACHE_LINE_SIZE,r0 dt r3 bf DC_Loop2 DC_NextWay: shlr8 r5; shlr2 r5 shlr2 r5; shlr2 r5 mov #1,r2 clrt subc r2,r5 /* iway -= 0x4000 */ bf DC_WayLoop nop; nop; nop; nop /* secure 8 insns before rts */ nop; nop; nop; nop /* XXX these 4 nops may not necessary */ ldc r7,sr /* UNBLOCK INTERRUPTS */ rts; mov #0,r0 /* return OK */ .align 2DC_X80000000: .long 0x80000000 /* CCR.EMODE */DC_X10000000: .long 0x10000000 /* SR.BL */DC_XFF00001C: .long 0xff00001c /* CCR address in P4 */DC_XF4000000: .long 0xf4000000 /* D-cache address array */DC_XF4001000: .long 0xf4001000 /* D-cache address array */DC_XF4002000: .long 0xf4002000 /* D-cache address array */DC_X2000: .word 0x2000DC_128: .word 128 /******************************************************************************** cacheSh7750IInvalOp - invalidate I-cache entries by associative purge** This routine clears V-bit in I-cache address array associatively. Note that* this operation does nothing if SH7750 MMU mishits I-TLB, thus this routine* is not reliable if MMU is enabled. This routine has to be executed on P2.** STATUS cacheSh7750IInvalOp (void *from, size_t bytes)* {* UINT32 ca = (UINT32)from & 0xffffffe0;** if (bytes == 0) return OK;** if (*CCR & CCR_IC_INDEX_ENABLE)* while (ca < (UINT32)from + bytes)* {* /@ In enhanced mode the A bit force an associative purge* @ by a comparison of the tag stored in the entry of each* @ way. Therefore the way bit 13 is not used. ^^^^* @/* *(UINT32 *)(0xf0000008 | (ca & 0xfe0) | ((ca & 0x2000000) >> 13))* = ca & 0xfffffc00;** ca += ICACHE_LINE_SIZE;* }* else* while (ca < (UINT32)from + bytes)* {* /@ In enhanced mode the A bit force an associative purge* @ by a comparison of the tag stored in the entry of each* @ way. Therefore the way bit 13 is not used. ^^^^* @/* *(UINT32 *)(0xf0000008 | (ca & 0x1fe0)) = ca & 0xfffffc00;** ca += ICACHE_LINE_SIZE;* }** return OK;* }** RETURNS: OK, always.** NOMANUAL*/ .type _cacheSh7750IInvalOp,@function .align _ALIGN_UNCACHED_TEXT_cacheSh7750IInvalOp: tst r5,r5 /* if (bytes == 0) */ bt II_Exit /* return OK; */ mov.l II_XF0000008,r2 add r4,r5 /* r5: from + bytes */ mov.w II_XFC00,r3 /* r3: 0xfffffc00 */ mov #0xe0,r0 /* r0: 0xffffffe0 */ mov.l II_XFF00001C,r1 /* r1: CCR address */ mov.l @r1,r1 /* r1: CCR value */ mov #0x80,r7 extu.b r7,r7 shll8 r7 /* r7: CCR_IC_INDEX_ENABLE */ tst r7,r1 /* check CCR_IC_INDEX_ENABLE bit */ bf.s II_Index_Mode /* if on, go to II_Index_Mode */ and r0,r4 /* r4: ca = from & 0xffffffe0 */ mov.w II_X1FE0,r6 /* r6: 0x00001fe0 (each way) */II_Loop: cmp/hs r5,r4 /* if (from + bytes <= ca) */ bt II_Exit /* return OK; */ mov r3,r0 /* r0: 0xfffffc00 */ mov r6,r1 /* r1: 0x00001fe0 */ and r4,r0 /* r0: ca & 0xfffffc00 */ and r4,r1 /* r1: ca & 0x00001fe0 */ or r2,r1 /* r1: 0xf0000008 | (ca & 0x1fe0) */ mov.l r0,@r1 /* purge cache entry associatively */ bra II_Loop; add #ICACHE_LINE_SIZE,r4 /* ca += ICACHE_LINE_SIZE */II_Index_Mode: mov.w II_XFE0,r6 /* r6: 0x00000fe0 */ mov #0x2,r7 shll16 r7 shll8 r7 /* r7: 0x02000000 */II_Loop_Index: cmp/hs r5,r4 /* if (from + bytes <= ca) */ bt II_Exit /* return OK; */ mov r6,r1 /* r1: 0x00000fe0 */ and r4,r1 /* r1: ca & 0x00000fe0 */ or r2,r1 /* r1: 0xf0000008 | (ca & 0xfe0) */ tst r7,r4 /* check A25 bit */ bt II_A25_Off /* if off, keep A12 bit off */ mov #0x10,r0 /* if on, enable A12 bit */ shll8 r0 /* r0: 0x00001000 */ or r0,r1 /* r1: 0xf0001008 | (ca & 0xfe0) */II_A25_Off: mov r3,r0 /* r0: 0xfffffc00 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -