Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/aim/mmu_radix.c
Show First 20 Lines • Show All 741 Lines • ▼ Show 20 Lines | tlbiel_radix_set_isa300(uint32_t set, uint32_t is, | ||||
rs = PPC_BITLSHIFT_VAL((uint64_t)pid, 31); | rs = PPC_BITLSHIFT_VAL((uint64_t)pid, 31); | ||||
__asm __volatile(PPC_TLBIEL(%0, %1, %2, %3, 1) | __asm __volatile(PPC_TLBIEL(%0, %1, %2, %3, 1) | ||||
: : "r"(rb), "r"(rs), "i"(ric), "i"(prs) | : : "r"(rb), "r"(rs), "i"(ric), "i"(prs) | ||||
: "memory"); | : "memory"); | ||||
} | } | ||||
static void | static void | ||||
tlbiel_flush_isa3(uint32_t num_sets, uint32_t is) | tlbiel_flush_isa3(int scope, uint32_t num_sets, uint32_t is) | ||||
{ | { | ||||
uint32_t set; | uint32_t set; | ||||
__asm __volatile("ptesync": : :"memory"); | __asm __volatile("ptesync": : :"memory"); | ||||
/* | /* | ||||
* Flush the first set of the TLB, and the entire Page Walk Cache | * Flush the first set of the TLB, and the entire Page Walk Cache | ||||
* and partition table entries. Then flush the remaining sets of the | * and partition table entries. Then flush the remaining sets of the | ||||
* TLB. | * TLB. | ||||
*/ | */ | ||||
if (scope == TLB_INVAL_SCOPE_GLOBAL) { | |||||
jhibbits: Can TLB_INVAL_SCOPE_* be renumbered to 2/3 instead of 0/1? That would avoid needing to pass… | |||||
tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0); | tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0); | ||||
for (set = 1; set < num_sets; set++) | for (set = 1; set < num_sets; set++) | ||||
tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0); | tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0); | ||||
} | |||||
/* Do the same for process scoped entries. */ | /* Do the same for process scoped entries. */ | ||||
tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1); | tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1); | ||||
for (set = 1; set < num_sets; set++) | for (set = 1; set < num_sets; set++) | ||||
tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); | tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); | ||||
__asm __volatile("ptesync": : :"memory"); | __asm __volatile("ptesync": : :"memory"); | ||||
} | } | ||||
static void | static void | ||||
mmu_radix_tlbiel_flush(int scope) | mmu_radix_tlbiel_flush(int scope) | ||||
{ | { | ||||
int is; | int is; | ||||
MPASS(scope == TLB_INVAL_SCOPE_LPID || | MPASS(scope == TLB_INVAL_SCOPE_LPID || | ||||
scope == TLB_INVAL_SCOPE_GLOBAL); | scope == TLB_INVAL_SCOPE_GLOBAL); | ||||
is = scope + 2; | is = scope + 2; | ||||
tlbiel_flush_isa3(POWER9_TLB_SETS_RADIX, is); | tlbiel_flush_isa3(scope, POWER9_TLB_SETS_RADIX, is); | ||||
__asm __volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); | __asm __volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); | ||||
} | } | ||||
static void | static void | ||||
mmu_radix_tlbie_all() | mmu_radix_tlbie_all() | ||||
{ | { | ||||
if (powernv_enabled) | if (powernv_enabled) | ||||
mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); | mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); | ||||
▲ Show 20 Lines • Show All 1,404 Lines • ▼ Show 20 Lines | mmu_radix_proctab_init(void) | ||||
if (powernv_enabled) { | if (powernv_enabled) { | ||||
mmu_radix_proctab_register(proctab0pa, PROCTAB_SIZE_SHIFT - 12); | mmu_radix_proctab_register(proctab0pa, PROCTAB_SIZE_SHIFT - 12); | ||||
__asm __volatile("ptesync" : : : "memory"); | __asm __volatile("ptesync" : : : "memory"); | ||||
__asm __volatile(PPC_TLBIE_5(%0,%1,2,1,1) : : | __asm __volatile(PPC_TLBIE_5(%0,%1,2,1,1) : : | ||||
"r" (TLBIEL_INVAL_SET_LPID), "r" (0)); | "r" (TLBIEL_INVAL_SET_LPID), "r" (0)); | ||||
__asm __volatile("eieio; tlbsync; ptesync" : : : "memory"); | __asm __volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||||
#ifdef PSERIES | #ifdef PSERIES | ||||
} else { | } else { | ||||
phyp_hcall(H_REGISTER_PROC_TBL, | int64_t rc; | ||||
rc = phyp_hcall(H_REGISTER_PROC_TBL, | |||||
PROC_TABLE_NEW | PROC_TABLE_RADIX | PROC_TABLE_GTSE, | PROC_TABLE_NEW | PROC_TABLE_RADIX | PROC_TABLE_GTSE, | ||||
proctab0pa, 0, PROCTAB_SIZE_SHIFT - 12); | proctab0pa, 0, PROCTAB_SIZE_SHIFT - 12); | ||||
if (rc != H_SUCCESS) | |||||
panic("mmu_radix_proctab_init: " | |||||
"failed to register process table: rc=%jd", | |||||
(intmax_t)rc); | |||||
#endif | #endif | ||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("process table %p and kernel radix PDE: %p\n", | printf("process table %p and kernel radix PDE: %p\n", | ||||
isa3_proctab, kernel_pmap->pm_pml1); | isa3_proctab, kernel_pmap->pm_pml1); | ||||
mtmsr(mfmsr() | PSL_DR ); | mtmsr(mfmsr() | PSL_DR ); | ||||
mtmsr(mfmsr() & ~PSL_DR); | mtmsr(mfmsr() & ~PSL_DR); | ||||
▲ Show 20 Lines • Show All 4,258 Lines • Show Last 20 Lines |
Can TLB_INVAL_SCOPE_* be renumbered to 2/3 instead of 0/1? That would avoid needing to pass the scope as extra.