Changeset View
Changeset View
Standalone View
Standalone View
head/sys/powerpc/pseries/mmu_phyp.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#include <powerpc/aim/mmu_oea64.h> | #include <powerpc/aim/mmu_oea64.h> | ||||
#include "mmu_if.h" | #include "mmu_if.h" | ||||
#include "moea64_if.h" | #include "moea64_if.h" | ||||
#include "phyp-hvcall.h" | #include "phyp-hvcall.h" | ||||
#define MMU_PHYP_DEBUG 0 | |||||
#define MMU_PHYP_ID "mmu_phyp: " | |||||
#if MMU_PHYP_DEBUG | |||||
#define dprintf(fmt, ...) printf(fmt, ## __VA_ARGS__) | |||||
#define dprintf0(fmt, ...) dprintf(MMU_PHYP_ID fmt, ## __VA_ARGS__) | |||||
#else | |||||
#define dprintf(fmt, args...) do { ; } while(0) | |||||
#define dprintf0(fmt, args...) do { ; } while(0) | |||||
#endif | |||||
static struct rmlock mphyp_eviction_lock; | static struct rmlock mphyp_eviction_lock; | ||||
/* | /* | ||||
* Kernel MMU interface | * Kernel MMU interface | ||||
*/ | */ | ||||
static void mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, | static void mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, | ||||
vm_offset_t kernelend); | vm_offset_t kernelend); | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) | ||||
res = OF_getencprop(node, "ibm,pft-size", prop, sizeof(prop)); | res = OF_getencprop(node, "ibm,pft-size", prop, sizeof(prop)); | ||||
if (res <= 0) | if (res <= 0) | ||||
panic("mmu_phyp: unknown PFT size"); | panic("mmu_phyp: unknown PFT size"); | ||||
final_pteg_count = 1 << prop[1]; | final_pteg_count = 1 << prop[1]; | ||||
res = OF_getencprop(node, "ibm,slb-size", prop, sizeof(prop[0])); | res = OF_getencprop(node, "ibm,slb-size", prop, sizeof(prop[0])); | ||||
if (res > 0) | if (res > 0) | ||||
n_slbs = prop[0]; | n_slbs = prop[0]; | ||||
dprintf0("slb-size=%i\n", n_slbs); | |||||
moea64_pteg_count = final_pteg_count / sizeof(struct lpteg); | moea64_pteg_count = final_pteg_count / sizeof(struct lpteg); | ||||
/* Clear any old page table entries */ | /* Clear any old page table entries */ | ||||
for (idx = 0; idx < moea64_pteg_count*8; idx++) { | for (idx = 0; idx < moea64_pteg_count*8; idx++) { | ||||
phyp_pft_hcall(H_READ, 0, idx, 0, 0, &old.pte_hi, | phyp_pft_hcall(H_READ, 0, idx, 0, 0, &old.pte_hi, | ||||
&old.pte_lo, &old.pte_lo); | &old.pte_lo, &old.pte_lo); | ||||
vsid = (old.pte_hi << (ADDR_API_SHFT64 - ADDR_PIDX_SHFT)) >> 28; | vsid = (old.pte_hi << (ADDR_API_SHFT64 - ADDR_PIDX_SHFT)) >> 28; | ||||
Show All 20 Lines | if (len > 0) { | ||||
res = OF_getencprop(node, "ibm,segment-page-sizes", arr, | res = OF_getencprop(node, "ibm,segment-page-sizes", arr, | ||||
sizeof(arr)); | sizeof(arr)); | ||||
len /= 4; | len /= 4; | ||||
idx = 0; | idx = 0; | ||||
while (len > 0) { | while (len > 0) { | ||||
shift = arr[idx]; | shift = arr[idx]; | ||||
slb_encoding = arr[idx + 1]; | slb_encoding = arr[idx + 1]; | ||||
nptlp = arr[idx + 2]; | nptlp = arr[idx + 2]; | ||||
dprintf0("Segment Page Size: " | |||||
"%uKB, slb_enc=0x%X: {size, encoding}[%u] =", | |||||
shift > 10? 1 << (shift-10) : 0, | |||||
slb_encoding, nptlp); | |||||
idx += 3; | idx += 3; | ||||
len -= 3; | len -= 3; | ||||
while (len > 0 && nptlp) { | while (len > 0 && nptlp) { | ||||
lp_size = arr[idx]; | lp_size = arr[idx]; | ||||
lp_encoding = arr[idx+1]; | lp_encoding = arr[idx+1]; | ||||
dprintf(" {%uKB, 0x%X}", | |||||
lp_size > 10? 1 << (lp_size-10) : 0, | |||||
lp_encoding); | |||||
if (slb_encoding == SLBV_L && lp_encoding == 0) | if (slb_encoding == SLBV_L && lp_encoding == 0) | ||||
break; | break; | ||||
idx += 2; | idx += 2; | ||||
len -= 2; | len -= 2; | ||||
nptlp--; | nptlp--; | ||||
} | } | ||||
dprintf("\n"); | |||||
if (nptlp && slb_encoding == SLBV_L && lp_encoding == 0) | if (nptlp && slb_encoding == SLBV_L && lp_encoding == 0) | ||||
break; | break; | ||||
} | } | ||||
if (len == 0) | if (len > 0) { | ||||
panic("Standard large pages (SLB[L] = 1, PTE[LP] = 0) " | |||||
"not supported by this system. Please enable huge " | |||||
"page backing if running under PowerKVM."); | |||||
moea64_large_page_shift = shift; | moea64_large_page_shift = shift; | ||||
moea64_large_page_size = 1ULL << lp_size; | moea64_large_page_size = 1ULL << lp_size; | ||||
moea64_large_page_mask = moea64_large_page_size - 1; | |||||
hw_direct_map = 1; | |||||
printf(MMU_PHYP_ID | |||||
"Support for hugepages of %uKB detected\n", | |||||
moea64_large_page_shift > 10? | |||||
1 << (moea64_large_page_shift-10) : 0); | |||||
} else { | |||||
moea64_large_page_size = 0; | |||||
moea64_large_page_shift = 0; | |||||
moea64_large_page_mask = 0; | |||||
hw_direct_map = 0; | |||||
printf(MMU_PHYP_ID | |||||
"Support for hugepages not found\n"); | |||||
} | |||||
} | } | ||||
moea64_mid_bootstrap(mmup, kernelstart, kernelend); | moea64_mid_bootstrap(mmup, kernelstart, kernelend); | ||||
moea64_late_bootstrap(mmup, kernelstart, kernelend); | moea64_late_bootstrap(mmup, kernelstart, kernelend); | ||||
/* Test for broken versions of KVM that don't conform to the spec */ | /* Test for broken versions of KVM that don't conform to the spec */ | ||||
if (phyp_hcall(H_CLEAR_MOD, 0, 0) == H_FUNCTION) | if (phyp_hcall(H_CLEAR_MOD, 0, 0) == H_FUNCTION) | ||||
brokenkvm = 1; | brokenkvm = 1; | ||||
▲ Show 20 Lines • Show All 256 Lines • Show Last 20 Lines |