SPCI: SPCI_FEATURES implementation.
Change-Id: I1bb3e32808d503ee75303a5e70b41645b2d7e86b
diff --git a/src/api.c b/src/api.c
index 92328c8..7c1f12a 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1705,3 +1705,25 @@
return 0;
}
+
+/**
+ * Discovery function returning information about the implementation of optional
+ * SPCI interfaces.
+ */
+struct spci_value api_spci_features(uint32_t function_id)
+{
+ switch (function_id) {
+ case SPCI_ERROR_32:
+ case SPCI_SUCCESS_32:
+ case SPCI_ID_GET_32:
+ case SPCI_YIELD_32:
+ case SPCI_VERSION_32:
+ case SPCI_FEATURES_32:
+ case SPCI_MSG_SEND_32:
+ case SPCI_MSG_POLL_32:
+ case SPCI_MSG_WAIT_32:
+ return (struct spci_value){.func = SPCI_SUCCESS_32};
+ default:
+ return spci_error(SPCI_NOT_SUPPORTED);
+ }
+}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index bbb115f..7928f54 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -312,6 +312,10 @@
static bool spci_handler(struct spci_value *args, struct vcpu **next)
{
+ /*
+ * NOTE: When adding new methods to this handler update
+ * api_spci_features accordingly.
+ */
switch (args->func & ~SMCCC_CONVENTION_MASK) {
case SPCI_VERSION_32:
*args = api_spci_version();
@@ -319,6 +323,9 @@
case SPCI_ID_GET_32:
*args = api_spci_id_get(current());
return true;
+ case SPCI_FEATURES_32:
+ *args = api_spci_features(args->arg1);
+ return true;
case SPCI_YIELD_32:
api_yield(current(), next);