|
@@ -168,6 +168,14 @@ static unsigned long __initdata prom_tce_alloc_start;
|
|
|
static unsigned long __initdata prom_tce_alloc_end;
|
|
|
#endif
|
|
|
|
|
|
+static bool __initdata prom_radix_disable;
|
|
|
+
|
|
|
+struct platform_support {
|
|
|
+ bool hash_mmu;
|
|
|
+ bool radix_mmu;
|
|
|
+ bool radix_gtse;
|
|
|
+};
|
|
|
+
|
|
|
/* Platforms codes are now obsolete in the kernel. Now only used within this
|
|
|
* file and ultimately gone too. Feel free to change them if you need, they
|
|
|
* are not shared with anything outside of this file anymore
|
|
@@ -626,6 +634,12 @@ static void __init early_cmdline_parse(void)
|
|
|
prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
|
|
|
#endif
|
|
|
}
|
|
|
+
|
|
|
+ opt = strstr(prom_cmd_line, "disable_radix");
|
|
|
+ if (opt) {
|
|
|
+ prom_debug("Radix disabled from cmdline\n");
|
|
|
+ prom_radix_disable = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
|
|
@@ -695,6 +709,8 @@ struct option_vector5 {
|
|
|
u8 byte22;
|
|
|
u8 intarch;
|
|
|
u8 mmu;
|
|
|
+ u8 hash_ext;
|
|
|
+ u8 radix_ext;
|
|
|
} __packed;
|
|
|
|
|
|
struct option_vector6 {
|
|
@@ -850,8 +866,9 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
|
|
|
.reserved3 = 0,
|
|
|
.subprocessors = 1,
|
|
|
.intarch = 0,
|
|
|
- .mmu = OV5_FEAT(OV5_MMU_RADIX_300) | OV5_FEAT(OV5_MMU_HASH_300) |
|
|
|
- OV5_FEAT(OV5_MMU_PROC_TBL) | OV5_FEAT(OV5_MMU_GTSE),
|
|
|
+ .mmu = 0,
|
|
|
+ .hash_ext = 0,
|
|
|
+ .radix_ext = 0,
|
|
|
},
|
|
|
|
|
|
/* option vector 6: IBM PAPR hints */
|
|
@@ -990,6 +1007,92 @@ static int __init prom_count_smt_threads(void)
|
|
|
|
|
|
}
|
|
|
|
|
|
+static void __init prom_parse_mmu_model(u8 val,
|
|
|
+ struct platform_support *support)
|
|
|
+{
|
|
|
+ switch (val) {
|
|
|
+ case OV5_FEAT(OV5_MMU_DYNAMIC):
|
|
|
+ case OV5_FEAT(OV5_MMU_EITHER): /* Either Available */
|
|
|
+ prom_debug("MMU - either supported\n");
|
|
|
+ support->radix_mmu = !prom_radix_disable;
|
|
|
+ support->hash_mmu = true;
|
|
|
+ break;
|
|
|
+ case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
|
|
|
+ prom_debug("MMU - radix only\n");
|
|
|
+ if (prom_radix_disable) {
|
|
|
+ /*
|
|
|
+ * If we __have__ to do radix, we're better off ignoring
|
|
|
+ * the command line rather than not booting.
|
|
|
+ */
|
|
|
+ prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
|
|
|
+ }
|
|
|
+ support->radix_mmu = true;
|
|
|
+ break;
|
|
|
+ case OV5_FEAT(OV5_MMU_HASH):
|
|
|
+ prom_debug("MMU - hash only\n");
|
|
|
+ support->hash_mmu = true;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ prom_debug("Unknown mmu support option: 0x%x\n", val);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void __init prom_parse_platform_support(u8 index, u8 val,
|
|
|
+ struct platform_support *support)
|
|
|
+{
|
|
|
+ switch (index) {
|
|
|
+ case OV5_INDX(OV5_MMU_SUPPORT): /* MMU Model */
|
|
|
+ prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
|
|
|
+ break;
|
|
|
+ case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
|
|
|
+ if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
|
|
|
+ prom_debug("Radix - GTSE supported\n");
|
|
|
+ support->radix_gtse = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void __init prom_check_platform_support(void)
|
|
|
+{
|
|
|
+ struct platform_support supported = {
|
|
|
+ .hash_mmu = false,
|
|
|
+ .radix_mmu = false,
|
|
|
+ .radix_gtse = false
|
|
|
+ };
|
|
|
+ int prop_len = prom_getproplen(prom.chosen,
|
|
|
+ "ibm,arch-vec-5-platform-support");
|
|
|
+ if (prop_len > 1) {
|
|
|
+ int i;
|
|
|
+ u8 vec[prop_len];
|
|
|
+ prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
|
|
|
+ prop_len);
|
|
|
+ prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
|
|
|
+ &vec, sizeof(vec));
|
|
|
+ for (i = 0; i < prop_len; i += 2) {
|
|
|
+ prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
|
|
|
+ , vec[i]
|
|
|
+ , vec[i + 1]);
|
|
|
+ prom_parse_platform_support(vec[i], vec[i + 1],
|
|
|
+ &supported);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (supported.radix_mmu && supported.radix_gtse) {
|
|
|
+ /* Radix preferred - but we require GTSE for now */
|
|
|
+ prom_debug("Asking for radix with GTSE\n");
|
|
|
+ ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
|
|
|
+ ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
|
|
|
+ } else if (supported.hash_mmu) {
|
|
|
+ /* Default to hash mmu (if we can) */
|
|
|
+ prom_debug("Asking for hash\n");
|
|
|
+ ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
|
|
|
+ } else {
|
|
|
+ /* We're probably on a legacy hypervisor */
|
|
|
+ prom_debug("Assuming legacy hash support\n");
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
static void __init prom_send_capabilities(void)
|
|
|
{
|
|
@@ -997,6 +1100,9 @@ static void __init prom_send_capabilities(void)
|
|
|
prom_arg_t ret;
|
|
|
u32 cores;
|
|
|
|
|
|
+ /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
|
|
|
+ prom_check_platform_support();
|
|
|
+
|
|
|
root = call_prom("open", 1, 1, ADDR("/"));
|
|
|
if (root != 0) {
|
|
|
/* We need to tell the FW about the number of cores we support.
|