|
@@ -37,13 +37,62 @@
|
|
|
#include <asm/kexec.h>
|
|
|
#include <asm/smp.h>
|
|
|
#include <asm/tm.h>
|
|
|
+#include <asm/setup.h>
|
|
|
|
|
|
#include "powernv.h"
|
|
|
|
|
|
+static void pnv_setup_rfi_flush(void)
|
|
|
+{
|
|
|
+ struct device_node *np, *fw_features;
|
|
|
+ enum l1d_flush_type type;
|
|
|
+ int enable;
|
|
|
+
|
|
|
+ /* Default to fallback in case fw-features are not available */
|
|
|
+ type = L1D_FLUSH_FALLBACK;
|
|
|
+ enable = 1;
|
|
|
+
|
|
|
+ np = of_find_node_by_name(NULL, "ibm,opal");
|
|
|
+ fw_features = of_get_child_by_name(np, "fw-features");
|
|
|
+ of_node_put(np);
|
|
|
+
|
|
|
+ if (fw_features) {
|
|
|
+ np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
|
|
|
+ if (np && of_property_read_bool(np, "enabled"))
|
|
|
+ type = L1D_FLUSH_MTTRIG;
|
|
|
+
|
|
|
+ of_node_put(np);
|
|
|
+
|
|
|
+ np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
|
|
|
+ if (np && of_property_read_bool(np, "enabled"))
|
|
|
+ type = L1D_FLUSH_ORI;
|
|
|
+
|
|
|
+ of_node_put(np);
|
|
|
+
|
|
|
+ /* Enable unless firmware says NOT to */
|
|
|
+ enable = 2;
|
|
|
+ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
|
|
|
+ if (np && of_property_read_bool(np, "disabled"))
|
|
|
+ enable--;
|
|
|
+
|
|
|
+ of_node_put(np);
|
|
|
+
|
|
|
+ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
|
|
|
+ if (np && of_property_read_bool(np, "disabled"))
|
|
|
+ enable--;
|
|
|
+
|
|
|
+ of_node_put(np);
|
|
|
+ of_node_put(fw_features);
|
|
|
+ }
|
|
|
+
|
|
|
+ setup_rfi_flush(type, enable > 0);
|
|
|
+}
|
|
|
+
|
|
|
static void __init pnv_setup_arch(void)
|
|
|
{
|
|
|
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
|
|
|
|
|
|
+ pnv_setup_rfi_flush();
|
|
|
+
|
|
|
/* Initialize SMP */
|
|
|
pnv_smp_init();
|
|
|
|