@@ -410,7 +410,8 @@ static int make_psci_node(libxl__gc *gc, void *fdt)
res = fdt_begin_node(fdt, "psci");
if (res) return res;
- res = fdt_property_compat(gc, fdt, 2, "arm,psci-0.2","arm,psci");
+ res = fdt_property_compat(gc, fdt, 3, "arm,psci-1.0",
+ "arm,psci-0.2", "arm,psci");
if (res) return res;
res = fdt_property_string(fdt, "method", "hvc");
@@ -637,6 +637,7 @@ static int make_psci_node(void *fdt, const struct dt_device_node *parent)
{
int res;
const char compat[] =
+ "arm,psci-1.0""\0"
"arm,psci-0.2""\0"
"arm,psci";
@@ -106,7 +106,11 @@ static int32_t do_psci_cpu_off(uint32_t power_state)
static uint32_t do_psci_0_2_version(void)
{
- return PSCI_VERSION(0, 2);
+ /*
+ * PSCI is backward compatible from 0.2. So we can bump the version
+ * without any issue.
+ */
+ return PSCI_VERSION(1, 1);
}
static register_t do_psci_0_2_cpu_suspend(uint32_t power_state,
@@ -191,6 +195,29 @@ static void do_psci_0_2_system_reset(void)
domain_shutdown(d,SHUTDOWN_reboot);
}
+static int32_t do_psci_1_0_features(uint32_t psci_func_id)
+{
+ /* /!\ Ordered by function ID and not name */
+ switch ( psci_func_id )
+ {
+ case PSCI_0_2_FN32_PSCI_VERSION:
+ case PSCI_0_2_FN32_CPU_SUSPEND:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
+ case PSCI_0_2_FN32_CPU_OFF:
+ case PSCI_0_2_FN32_CPU_ON:
+ case PSCI_0_2_FN64_CPU_ON:
+ case PSCI_0_2_FN32_AFFINITY_INFO:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
+ case PSCI_0_2_FN32_MIGRATE_INFO_TYPE:
+ case PSCI_0_2_FN32_SYSTEM_OFF:
+ case PSCI_0_2_FN32_SYSTEM_RESET:
+ case PSCI_1_0_FN32_PSCI_FEATURES:
+ return 0;
+ default:
+ return PSCI_NOT_SUPPORTED;
+ }
+}
+
#define PSCI_SET_RESULT(reg, val) set_user_reg(reg, 0, val)
#define PSCI_ARG(reg, n) get_user_reg(reg, n)
@@ -304,6 +331,16 @@ bool do_vpsci_0_2_call(struct cpu_user_regs *regs, uint32_t fid)
PSCI_SET_RESULT(regs, do_psci_0_2_affinity_info(taff, laff));
return true;
}
+
+ case PSCI_1_0_FN32_PSCI_FEATURES:
+ {
+ uint32_t psci_func_id = PSCI_ARG32(regs, 1);
+
+ perfc_incr(vpsci_features);
+ PSCI_SET_RESULT(regs, do_psci_1_0_features(psci_func_id));
+ return true;
+ }
+
default:
return false;
}
@@ -31,6 +31,7 @@ PERFCOUNTER(vpsci_system_off, "vpsci: system_off")
PERFCOUNTER(vpsci_system_reset, "vpsci: system_reset")
PERFCOUNTER(vpsci_cpu_suspend, "vpsci: cpu_suspend")
PERFCOUNTER(vpsci_cpu_affinity_info, "vpsci: cpu_affinity_info")
+PERFCOUNTER(vpsci_features, "vpsci: features")
PERFCOUNTER(vgicd_reads, "vgicd: read")
PERFCOUNTER(vgicd_writes, "vgicd: write")
@@ -40,6 +40,7 @@ void call_psci_system_reset(void);
#define PSCI_0_2_FN32_MIGRATE_INFO_TYPE PSCI_0_2_FN32(6)
#define PSCI_0_2_FN32_SYSTEM_OFF PSCI_0_2_FN32(8)
#define PSCI_0_2_FN32_SYSTEM_RESET PSCI_0_2_FN32(9)
+#define PSCI_1_0_FN32_PSCI_FEATURES PSCI_0_2_FN32(10)
#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1)
#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3)
@@ -23,7 +23,7 @@
#include <asm/psci.h>
/* Number of function implemented by virtual PSCI (only 0.2 or later) */
-#define VPSCI_NR_FUNCS 11
+#define VPSCI_NR_FUNCS 12
/* Functions handle PSCI calls from the guests */
bool do_vpsci_0_1_call(struct cpu_user_regs *regs, uint32_t fid);