^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* tsb.S: Sparc64 TSB table handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2006 David S. Miller <davem@davemloft.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/tsb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/cpudata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Invoked from TLB miss handler, we are in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * MMU global registers and they are setup like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * %g1: TSB entry pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * %g2: available temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * %g3: FAULT_CODE_{D,I}TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * %g4: available temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * %g5: available temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * %g6: TAG TARGET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * %g7: available temporary, will be loaded by us with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the physical address base of the linux page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * tables for the current address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) tsb_miss_dtlb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) mov TLB_TAG_ACCESS, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ldxa [%g4] ASI_DMMU, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) srlx %g4, PAGE_SHIFT, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ba,pt %xcc, tsb_miss_page_table_walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) sllx %g4, PAGE_SHIFT, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) tsb_miss_itlb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mov TLB_TAG_ACCESS, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ldxa [%g4] ASI_IMMU, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) srlx %g4, PAGE_SHIFT, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ba,pt %xcc, tsb_miss_page_table_walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) sllx %g4, PAGE_SHIFT, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* At this point we have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * %g1 -- PAGE_SIZE TSB entry address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * %g3 -- FAULT_CODE_{D,I}TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * %g4 -- missing virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * %g6 -- TAG TARGET (vaddr >> 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) tsb_miss_page_table_walk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) TRAP_LOAD_TRAP_BLOCK(%g7, %g5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Before committing to a full page table walk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * check the huge page TSB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 661: ldx [%g7 + TRAP_PER_CPU_TSB_HUGE], %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mov SCRATCHPAD_UTSBREG2, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ldxa [%g5] ASI_SCRATCHPAD, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) cmp %g5, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) be,pt %xcc, 80f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* We need an aligned pair of registers containing 2 values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * which can be easily rematerialized. %g6 and %g7 foot the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * bill just nicely. We'll save %g6 away into %g2 for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * huge page TSB TAG comparison.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Perform a huge page TSB lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mov %g6, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) and %g5, 0x7, %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mov 512, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) andn %g5, 0x7, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) sllx %g7, %g6, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) srlx %g4, REAL_HPAGE_SHIFT, %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) sub %g7, 1, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) and %g6, %g7, %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) sllx %g6, 4, %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) add %g5, %g6, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) TSB_LOAD_QUAD(%g5, %g6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) cmp %g6, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) be,a,pt %xcc, tsb_tlb_reload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mov %g7, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* No match, remember the huge page TSB entry address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * and restore %g6 and %g7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) TRAP_LOAD_TRAP_BLOCK(%g7, %g6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) srlx %g4, 22, %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 80: stx %g5, [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* At this point we have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * %g1 -- TSB entry address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * %g3 -- FAULT_CODE_{D,I}TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * %g4 -- missing virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * %g6 -- TAG TARGET (vaddr >> 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * %g7 -- page table physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * We know that both the base PAGE_SIZE TSB and the HPAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * TSB both lack a matching entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) tsb_miss_page_table_walk_sun4v_fastpath:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) USER_PGTABLE_WALK_TL1(%g4, %g7, %g5, %g2, tsb_do_fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Valid PTE is now in %g5. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) sethi %uhi(_PAGE_PMD_HUGE | _PAGE_PUD_HUGE), %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sllx %g7, 32, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) andcc %g5, %g7, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) be,pt %xcc, 60f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* It is a huge page, use huge page TSB entry address we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * calculated above. If the huge page TSB has not been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * allocated, setup a trap stack and call hugetlb_setup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * to do so, then return from the trap to replay the TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * miss.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * This is necessary to handle the case of transparent huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * pages where we don't really have a non-atomic context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * in which to allocate the hugepage TSB hash table. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * the 'mm' faults in the hugepage for the first time, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * thus handle it here. This also makes sure that we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * allocate the TSB hash table on the correct NUMA node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) TRAP_LOAD_TRAP_BLOCK(%g7, %g2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cmp %g1, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bne,pt %xcc, 60f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 661: rdpr %pstate, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SET_GL(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) rdpr %tl, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) cmp %g7, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bne,pn %xcc, winfix_trampoline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mov %g3, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ba,pt %xcc, etrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) rd %pc, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) call hugetlb_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) add %sp, PTREGS_OFF, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ba,pt %xcc, rtrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* At this point we have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * %g1 -- TSB entry address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * %g3 -- FAULT_CODE_{D,I}TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * %g5 -- valid PTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * %g6 -- TAG TARGET (vaddr >> 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) tsb_reload:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) TSB_LOCK_TAG(%g1, %g2, %g7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) TSB_WRITE(%g1, %g5, %g6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Finally, load TLB and return from trap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) tsb_tlb_reload:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) cmp %g3, FAULT_CODE_DTLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bne,pn %xcc, tsb_itlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) tsb_dtlb_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 661: stxa %g5, [%g0] ASI_DTLB_DATA_IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* For sun4v the ASI_DTLB_DATA_IN store and the retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * instruction get nop'd out and we get here to branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * to the sun4v tlb load code. The registers are setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * %g4: vaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * %g5: PTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * %g6: TAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * The sun4v TLB load wants the PTE in %g3 so we fix that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * up here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ba,pt %xcc, sun4v_dtlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mov %g5, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) tsb_itlb_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Executable bit must be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 661: sethi %hi(_PAGE_EXEC_4U), %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) andcc %g5, %g4, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) andcc %g5, _PAGE_EXEC_4V, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) be,pn %xcc, tsb_do_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 661: stxa %g5, [%g0] ASI_ITLB_DATA_IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* For sun4v the ASI_ITLB_DATA_IN store and the retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * instruction get nop'd out and we get here to branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * to the sun4v tlb load code. The registers are setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * %g4: vaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * %g5: PTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * %g6: TAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * The sun4v TLB load wants the PTE in %g3 so we fix that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * up here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ba,pt %xcc, sun4v_itlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mov %g5, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* No valid entry in the page tables, do full fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .globl tsb_do_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) tsb_do_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cmp %g3, FAULT_CODE_DTLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 661: rdpr %pstate, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) SET_GL(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ldxa [%g0] ASI_SCRATCHPAD, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) bne,pn %xcc, tsb_do_itlb_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) tsb_do_dtlb_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) rdpr %tl, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) cmp %g3, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 661: mov TLB_TAG_ACCESS, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ldxa [%g4] ASI_DMMU, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .section .sun4v_2insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ldx [%g4 + HV_FAULT_D_ADDR_OFFSET], %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* Clear context ID bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) srlx %g5, PAGE_SHIFT, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) sllx %g5, PAGE_SHIFT, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) be,pt %xcc, sparc64_realfault_common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mov FAULT_CODE_DTLB, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ba,pt %xcc, winfix_trampoline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tsb_do_itlb_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) rdpr %tpc, %g5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ba,pt %xcc, sparc64_realfault_common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mov FAULT_CODE_ITLB, %g4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .globl sparc64_realfault_common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sparc64_realfault_common:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* fault code in %g4, fault address in %g5, etrap will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * preserve these two values in %l4 and %l5 respectively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ba,pt %xcc, etrap ! Save trap state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 1: rd %pc, %g7 ! ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) stb %l4, [%g6 + TI_FAULT_CODE] ! Save fault code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) stx %l5, [%g6 + TI_FAULT_ADDR] ! Save fault address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) call do_sparc64_fault ! Call fault handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) add %sp, PTREGS_OFF, %o0 ! Compute pt_regs arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ba,pt %xcc, rtrap ! Restore cpu state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) nop ! Delay slot (fill me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) winfix_trampoline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) rdpr %tpc, %g3 ! Prepare winfixup TNPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) or %g3, 0x7c, %g3 ! Compute branch offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) wrpr %g3, %tnpc ! Write it into TNPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) done ! Trap return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Insert an entry into the TSB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * %o0: TSB entry pointer (virt or phys address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * %o1: tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * %o2: pte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .globl __tsb_insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) __tsb_insert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) rdpr %pstate, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) wrpr %o5, PSTATE_IE, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) TSB_LOCK_TAG(%o0, %g2, %g3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) TSB_WRITE(%o0, %o2, %o1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) wrpr %o5, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .size __tsb_insert, .-__tsb_insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* Flush the given TSB entry if it has the matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * %o0: TSB entry pointer (virt or phys address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * %o1: tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .globl tsb_flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .type tsb_flush,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) tsb_flush:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) sethi %hi(TSB_TAG_LOCK_HIGH), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 1: TSB_LOAD_TAG(%o0, %g1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) srlx %g1, 32, %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) andcc %o3, %g2, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) bne,pn %icc, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) cmp %g1, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) mov 1, %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) bne,pt %xcc, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) sllx %o3, TSB_TAG_INVALID_BIT, %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) TSB_CAS_TAG(%o0, %g1, %o3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cmp %g1, %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) bne,pn %xcc, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 2: retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .size tsb_flush, .-tsb_flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Reload MMU related context switch state at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * schedule() time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * %o0: page table physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * %o1: TSB base config pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * %o2: TSB huge config pointer, or NULL if none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * %o3: Hypervisor TSB descriptor physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * %o4: Secondary context to load, if non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * We have to run this whole thing with interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * disabled so that the current cpu doesn't change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * due to preemption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .globl __tsb_context_switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .type __tsb_context_switch,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) __tsb_context_switch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rdpr %pstate, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) wrpr %g1, PSTATE_IE, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) brz,pn %o4, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mov SECONDARY_CONTEXT, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 661: stxa %o4, [%o5] ASI_DMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .section .sun4v_1insn_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) stxa %o4, [%o5] ASI_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) flush %g6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) stx %o0, [%g2 + TRAP_PER_CPU_PGD_PADDR]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ldx [%o1 + TSB_CONFIG_REG_VAL], %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) brz,pt %o2, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mov -1, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ldx [%o2 + TSB_CONFIG_REG_VAL], %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 1: stx %g3, [%g2 + TRAP_PER_CPU_TSB_HUGE]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sethi %hi(tlb_type), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) lduw [%g2 + %lo(tlb_type)], %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) cmp %g2, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bne,pt %icc, 50f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* Hypervisor TSB switch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) mov SCRATCHPAD_UTSBREG1, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) stxa %o0, [%o5] ASI_SCRATCHPAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) mov SCRATCHPAD_UTSBREG2, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) stxa %g3, [%o5] ASI_SCRATCHPAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mov 2, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) cmp %g3, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) move %xcc, 1, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mov HV_FAST_MMU_TSB_CTXNON0, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mov %o3, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ta HV_FAST_TRAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* Finish up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ba,pt %xcc, 9f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* SUN4U TSB switch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 50: mov TSB_REG, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) stxa %o0, [%o5] ASI_DMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) stxa %o0, [%o5] ASI_IMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 2: ldx [%o1 + TSB_CONFIG_MAP_VADDR], %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) brz %o4, 9f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ldx [%o1 + TSB_CONFIG_MAP_PTE], %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sethi %hi(sparc64_highest_unlocked_tlb_ent), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mov TLB_TAG_ACCESS, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) lduw [%g2 + %lo(sparc64_highest_unlocked_tlb_ent)], %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) stxa %o4, [%g3] ASI_DMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) sllx %g2, 3, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) stxa %o5, [%g2] ASI_DTLB_DATA_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) brz,pt %o2, 9f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ldx [%o2 + TSB_CONFIG_MAP_VADDR], %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ldx [%o2 + TSB_CONFIG_MAP_PTE], %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) mov TLB_TAG_ACCESS, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) stxa %o4, [%g3] ASI_DMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) sub %g2, (1 << 3), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) stxa %o5, [%g2] ASI_DTLB_DATA_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) wrpr %g1, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .size __tsb_context_switch, .-__tsb_context_switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #define TSB_PASS_BITS ((1 << TSB_TAG_LOCK_BIT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) (1 << TSB_TAG_INVALID_BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .globl copy_tsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .type copy_tsb,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) copy_tsb: /* %o0=old_tsb_base, %o1=old_tsb_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * %o2=new_tsb_base, %o3=new_tsb_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * %o4=page_size_shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) sethi %uhi(TSB_PASS_BITS), %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) srlx %o3, 4, %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) add %o0, %o1, %o1 /* end of old tsb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) sllx %g7, 32, %g7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sub %o3, 1, %o3 /* %o3 == new tsb hash mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) mov %o4, %g1 /* page_size_shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 661: prefetcha [%o0] ASI_N, #one_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .section .tsb_phys_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) prefetcha [%o0] ASI_PHYS_USE_EC, #one_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 90: andcc %o0, (64 - 1), %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) bne 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) add %o0, 64, %o5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 661: prefetcha [%o5] ASI_N, #one_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .section .tsb_phys_patch, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .word 661b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) prefetcha [%o5] ASI_PHYS_USE_EC, #one_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 1: TSB_LOAD_QUAD(%o0, %g2) /* %g2/%g3 == TSB entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) andcc %g2, %g7, %g0 /* LOCK or INVALID set? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) bne,pn %xcc, 80f /* Skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) sllx %g2, 22, %o4 /* TAG --> VADDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* This can definitely be computed faster... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) srlx %o0, 4, %o5 /* Build index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) and %o5, 511, %o5 /* Mask index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) sllx %o5, %g1, %o5 /* Put into vaddr position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) or %o4, %o5, %o4 /* Full VADDR. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) srlx %o4, %g1, %o4 /* Shift down to create index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) and %o4, %o3, %o4 /* Mask with new_tsb_nents-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) sllx %o4, 4, %o4 /* Shift back up into tsb ent offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) TSB_STORE(%o2 + %o4, %g2) /* Store TAG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) add %o4, 0x8, %o4 /* Advance to TTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) TSB_STORE(%o2 + %o4, %g3) /* Store TTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 80: add %o0, 16, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cmp %o0, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) bne,pt %xcc, 90b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .size copy_tsb, .-copy_tsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* Set the invalid bit in all TSB entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .globl tsb_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .type tsb_init,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) tsb_init: /* %o0 = TSB vaddr, %o1 = size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) prefetch [%o0 + 0x000], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) mov 1, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) prefetch [%o0 + 0x040], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) sllx %g1, TSB_TAG_INVALID_BIT, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) prefetch [%o0 + 0x080], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 1: prefetch [%o0 + 0x0c0], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) stx %g1, [%o0 + 0x00]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) stx %g1, [%o0 + 0x10]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) stx %g1, [%o0 + 0x20]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) stx %g1, [%o0 + 0x30]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) prefetch [%o0 + 0x100], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) stx %g1, [%o0 + 0x40]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) stx %g1, [%o0 + 0x50]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) stx %g1, [%o0 + 0x60]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) stx %g1, [%o0 + 0x70]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) prefetch [%o0 + 0x140], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) stx %g1, [%o0 + 0x80]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) stx %g1, [%o0 + 0x90]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) stx %g1, [%o0 + 0xa0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) stx %g1, [%o0 + 0xb0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) prefetch [%o0 + 0x180], #n_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) stx %g1, [%o0 + 0xc0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) stx %g1, [%o0 + 0xd0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) stx %g1, [%o0 + 0xe0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) stx %g1, [%o0 + 0xf0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) subcc %o1, 0x100, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bne,pt %xcc, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) add %o0, 0x100, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .size tsb_init, .-tsb_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .globl NGtsb_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .type NGtsb_init,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) NGtsb_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) rd %asi, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mov 1, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) sllx %g1, TSB_TAG_INVALID_BIT, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 1: stxa %g1, [%o0 + 0x00] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) stxa %g1, [%o0 + 0x10] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) stxa %g1, [%o0 + 0x20] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) stxa %g1, [%o0 + 0x30] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) stxa %g1, [%o0 + 0x40] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) stxa %g1, [%o0 + 0x50] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) stxa %g1, [%o0 + 0x60] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) stxa %g1, [%o0 + 0x70] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) stxa %g1, [%o0 + 0x80] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) stxa %g1, [%o0 + 0x90] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) stxa %g1, [%o0 + 0xa0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) stxa %g1, [%o0 + 0xb0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) stxa %g1, [%o0 + 0xc0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) stxa %g1, [%o0 + 0xd0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) stxa %g1, [%o0 + 0xe0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) stxa %g1, [%o0 + 0xf0] %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) subcc %o1, 0x100, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bne,pt %xcc, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) add %o0, 0x100, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) wr %g2, 0x0, %asi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .size NGtsb_init, .-NGtsb_init