^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef __ASM_TLB_MMU_V1_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define __ASM_TLB_MMU_V1_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #if defined(__ASSEMBLY__) && (CONFIG_ARC_MMU_VER == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) .macro TLB_WRITE_HEURISTICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define JH_HACK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #undef JH_HACK2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #undef JH_HACK3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #ifdef JH_HACK3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) ; Calculate set index for 2-way MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) ; -avoiding use of GetIndex from MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ; and its unpleasant LFSR pseudo-random sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ; r1 = TLBPD0 from TLB_RELOAD above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ; -- jh_ex_way_set not cleared on startup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ; didn't want to change setup.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ; hence extra instruction to clean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ; -- should be in cache since in same line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ; as r0/r1 saves above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ld r0,[jh_ex_way_sel] ; victim pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) and r0,r0,1 ; clean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) xor.f r0,r0,1 ; flip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) st r0,[jh_ex_way_sel] ; store back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) asr r0,r1,12 ; get set # <<1, note bit 12=R=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) or.nz r0,r0,1 ; set way bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) and r0,r0,0xff ; clean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) sr r0,[ARC_REG_TLBINDEX]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #ifdef JH_HACK2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ; JH hack #2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ; Faster than hack #1 in non-thrash case, but hard-coded for 2-way MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ; Slower in thrash case (where it matters) because more code is executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ; Inefficient due to two-register paradigm of this miss handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* r1 = data TLBPD0 at this point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) lr r0,[eret] /* instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) xor r0,r0,r1 /* compare set # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) and.f r0,r0,0x000fe000 /* 2-way MMU mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) bne 88f /* not in same set - no need to probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) lr r0,[eret] /* instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) and r0,r0,PAGE_MASK /* VPN of instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ; lr r1,[ARC_REG_TLBPD0] /* Data VPN+ASID - already in r1 from TLB_RELOAD*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) and r1,r1,0xff /* Data ASID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) or r0,r0,r1 /* Instruction address + Data ASID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) lr r1,[ARC_REG_TLBPD0] /* save TLBPD0 containing data TLB*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) sr r0,[ARC_REG_TLBPD0] /* write instruction address to TLBPD0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) sr TLBProbe, [ARC_REG_TLBCOMMAND] /* Look for instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) lr r0,[ARC_REG_TLBINDEX] /* r0 = index where instruction is, if at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) sr r1,[ARC_REG_TLBPD0] /* restore TLBPD0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) xor r0,r0,1 /* flip bottom bit of data index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) b.d 89f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) sr r0,[ARC_REG_TLBINDEX] /* and put it back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 88:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) sr TLBGetIndex, [ARC_REG_TLBCOMMAND]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 89:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #ifdef JH_HACK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ; Always checks whether instruction will be kicked out by dtlb miss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) mov_s r3, r1 ; save PD0 prepared by TLB_RELOAD in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) lr r0,[eret] /* instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) and r0,r0,PAGE_MASK /* VPN of instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) bmsk r1,r3,7 /* Data ASID, bits 7-0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) or_s r0,r0,r1 /* Instruction address + Data ASID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) sr r0,[ARC_REG_TLBPD0] /* write instruction address to TLBPD0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) sr TLBProbe, [ARC_REG_TLBCOMMAND] /* Look for instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) lr r0,[ARC_REG_TLBINDEX] /* r0 = index where instruction is, if at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) sr r3,[ARC_REG_TLBPD0] /* restore TLBPD0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sr TLBGetIndex, [ARC_REG_TLBCOMMAND]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) lr r1,[ARC_REG_TLBINDEX] /* r1 = index where MMU wants to put data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) cmp r0,r1 /* if no match on indices, go around */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) xor.eq r1,r1,1 /* flip bottom bit of data index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sr r1,[ARC_REG_TLBINDEX] /* and put it back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #endif