diff mbox series

[v2,07/12] firmware: scmi: fake base protocol commands on sandbox

Message ID 20230726083808.140780-8-takahiro.akashi@linaro.org
State Superseded
Headers show
Series firmware: scmi: add SCMI base protocol support | expand

Commit Message

AKASHI Takahiro July 26, 2023, 8:38 a.m. UTC
This is a simple implementation of SCMI base protocol for sandbox.
The main use is in SCMI unit test.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 drivers/firmware/scmi/sandbox-scmi_agent.c | 359 ++++++++++++++++++++-
 1 file changed, 358 insertions(+), 1 deletion(-)

Comments

Etienne CARRIERE Aug. 3, 2023, 10:21 a.m. UTC | #1
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Sent: Wednesday, July 26, 2023 10:38
>  
> This is a simple implementation of SCMI base protocol for sandbox.
> The main use is in SCMI unit test.
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Etienne Carriere <etienne.carriere@foss.st.com>
with reported typo addressed.


> ---
>  drivers/firmware/scmi/sandbox-scmi_agent.c | 359 ++++++++++++++++++++-
>  1 file changed, 358 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
> index 031882998dfa..1f0261ea5c94 100644
> --- a/drivers/firmware/scmi/sandbox-scmi_agent.c
> +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
> @@ -14,11 +14,14 @@
>  #include <asm/io.h>
>  #include <asm/scmi_test.h>
>  #include <dm/device_compat.h>
> +#include <linux/bitfield.h>
> +#include <linux/kernel.h>
>  
>  /*
>   * The sandbox SCMI agent driver simulates to some extend a SCMI message
>   * processing. It simulates few of the SCMI services for some of the
>   * SCMI protocols embedded in U-Boot. Currently:
> + * - SCMI base protocol
>   * - SCMI clock protocol emulates an agent exposing 2 clocks
>   * - SCMI reset protocol emulates an agent exposing a reset controller
>   * - SCMI voltage domain protocol emulates an agent exposing 2 regulators
> @@ -33,6 +36,21 @@
>   * various uclass devices, as clocks and reset controllers.
>   */
>  
> +#define SANDBOX_SCMI_BASE_PROTOCOL_VERSION SCMI_BASE_PROTOCOL_VERSION
> +#define SANDBOX_SCMI_VENDOR "U-Boot"
> +#define SANDBOX_SCMI_SUB_VENDOR "Sandbox"
> +#define SANDBOX_SCMI_IMPL_VERSION 0x1
> +#define SANDBOX_SCMI_AGENT_NAME "OSPM"
> +#define SANDBOX_SCMI_PLATFORM_NAME "platform"
> +
> +static u8 protocols[] = {
> +       SCMI_PROTOCOL_ID_CLOCK,
> +       SCMI_PROTOCOL_ID_RESET_DOMAIN,
> +       SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
> +};
> +
> +#define NUM_PROTOCOLS ARRAY_SIZE(protocols)
> +
>  static struct sandbox_scmi_clk scmi_clk[] = {
>          { .rate = 333 },
>          { .rate = 200 },
> @@ -114,6 +132,316 @@ static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint domain_id)
>   * Sandbox SCMI agent ops
>   */
>  
> +/* Base Protocol */
> +
> +/**
> + * sandbox_scmi_base_protocol_version - implement SCMI_BASE_PROTOCOL_VERSION
> + * @udevice:   SCMI device

typo: s/udevice/dev/g here and in the other function inline descripion
comments below.

BR,
etienne


> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_PROTOCOL_VERSION command.
> + */
> +static int sandbox_scmi_base_protocol_version(struct udevice *dev,
> +                                             struct scmi_msg *msg)
> +{
> +       struct scmi_protocol_version_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_protocol_version_out *)msg->out_msg;
> +       out->version = SANDBOX_SCMI_BASE_PROTOCOL_VERSION;
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_protocol_attrs - implement SCMI_BASE_PROTOCOL_ATTRIBUTES
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_PROTOCOL_ATTRIBUTES command.
> + */
> +static int sandbox_scmi_base_protocol_attrs(struct udevice *dev,
> +                                           struct scmi_msg *msg)
> +{
> +       struct scmi_protocol_attrs_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_protocol_attrs_out *)msg->out_msg;
> +       out->attributes = FIELD_PREP(0xff00, 2) | NUM_PROTOCOLS;
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_message_attrs - implement
> + *                                     SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES command.
> + */
> +static int sandbox_scmi_base_message_attrs(struct udevice *dev,
> +                                          struct scmi_msg *msg)
> +{
> +       u32 message_id;
> +       struct scmi_protocol_msg_attrs_out *out = NULL;
> +
> +       if (!msg->in_msg || msg->in_msg_sz < sizeof(message_id) ||
> +           !msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       message_id = *(u32 *)msg->in_msg;
> +       out = (struct scmi_protocol_msg_attrs_out *)msg->out_msg;
> +
> +       if (message_id >= SCMI_PROTOCOL_VERSION &&
> +           message_id <= SCMI_BASE_RESET_AGENT_CONFIGURATION &&
> +           message_id != SCMI_BASE_NOTIFY_ERRORS) {
> +               out->attributes = 0;
> +               out->status = SCMI_SUCCESS;
> +       } else {
> +               out->status = SCMI_NOT_FOUND;
> +       }
> +
> +               return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_discover_vendor - implement SCMI_BASE_DISCOVER_VENDOR
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_DISCOVER_VENDOR command
> + */
> +static int sandbox_scmi_base_discover_vendor(struct udevice *dev,
> +                                            struct scmi_msg *msg)
> +{
> +       struct scmi_base_discover_vendor_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
> +       strcpy(out->vendor_identifier, SANDBOX_SCMI_VENDOR);
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_discover_sub_vendor - implement
> + *                                             SCMI_BASE_DISCOVER_SUB_VENDOR
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_DISCOVER_SUB_VENDOR command
> + */
> +static int sandbox_scmi_base_discover_sub_vendor(struct udevice *dev,
> +                                                struct scmi_msg *msg)
> +{
> +       struct scmi_base_discover_vendor_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
> +       strcpy(out->vendor_identifier, SANDBOX_SCMI_SUB_VENDOR);
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_discover_impl_version - implement
> + *                             SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION command
> + */
> +static int sandbox_scmi_base_discover_impl_version(struct udevice *dev,
> +                                                  struct scmi_msg *msg)
> +{
> +       struct scmi_base_discover_impl_version_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_base_discover_impl_version_out *)msg->out_msg;
> +       out->impl_version = SANDBOX_SCMI_IMPL_VERSION;
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_discover_list_protocols - implement
> + *                                     SCMI_BASE_DISCOVER_LIST_PROTOCOLS
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_DISCOVER_LIST_PROTOCOLS command
> + */
> +static int sandbox_scmi_base_discover_list_protocols(struct udevice *dev,
> +                                                    struct scmi_msg *msg)
> +{
> +       struct scmi_base_discover_list_protocols_out *out = NULL;
> +
> +       if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       out = (struct scmi_base_discover_list_protocols_out *)msg->out_msg;
> +       memcpy(out->protocols, protocols, sizeof(protocols));
> +       out->num_protocols = NUM_PROTOCOLS;
> +       out->status = SCMI_SUCCESS;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_discover_agent - implement SCMI_BASE_DISCOVER_AGENT
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_DISCOVER_AGENT command
> + */
> +static int sandbox_scmi_base_discover_agent(struct udevice *dev,
> +                                           struct scmi_msg *msg)
> +{
> +       u32 agent_id;
> +       struct scmi_base_discover_agent_out *out = NULL;
> +
> +       if (!msg->in_msg || msg->in_msg_sz < sizeof(agent_id) ||
> +           !msg->out_msg || msg->out_msg_sz < sizeof(*out))
> +               return -EINVAL;
> +
> +       agent_id = *(u32 *)msg->in_msg;
> +       out = (struct scmi_base_discover_agent_out *)msg->out_msg;
> +       out->status = SCMI_SUCCESS;
> +       if (agent_id == 0xffffffff || agent_id == 1) {
> +               out->agent_id = 1;
> +               strcpy(out->name, SANDBOX_SCMI_AGENT_NAME);
> +       } else if (!agent_id) {
> +               out->agent_id = agent_id;
> +               strcpy(out->name, SANDBOX_SCMI_PLATFORM_NAME);
> +       } else {
> +               out->status = SCMI_NOT_FOUND;
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_set_device_permissions - implement
> + *                                             SCMI_BASE_SET_DEVICE_PERMISSIONS
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_SET_DEVICE_PERMISSIONS command
> + */
> +static int sandbox_scmi_base_set_device_permissions(struct udevice *dev,
> +                                                   struct scmi_msg *msg)
> +{
> +       struct scmi_base_set_device_permissions_in *in = NULL;
> +       u32 *status;
> +
> +       if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
> +           !msg->out_msg || msg->out_msg_sz < sizeof(*status))
> +               return -EINVAL;
> +
> +       in = (struct scmi_base_set_device_permissions_in *)msg->in_msg;
> +       status = (u32 *)msg->out_msg;
> +
> +       if (in->agent_id != 1 || in->device_id != 0)
> +               *status = SCMI_NOT_FOUND;
> +       else if (in->flags & ~SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
> +               *status = SCMI_INVALID_PARAMETERS;
> +       else if (in->flags & SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
> +               *status = SCMI_SUCCESS;
> +       else
> +               /* unset not allowed */
> +               *status = SCMI_DENIED;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_set_protocol_permissions - implement
> + *                                     SCMI_BASE_SET_PROTOCOL_PERMISSIONS
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_SET_PROTOCOL_PERMISSIONS command
> + */
> +static int sandbox_scmi_base_set_protocol_permissions(struct udevice *dev,
> +                                                     struct scmi_msg *msg)
> +{
> +       struct scmi_base_set_protocol_permissions_in *in = NULL;
> +       u32 *status;
> +       int i;
> +
> +       if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
> +           !msg->out_msg || msg->out_msg_sz < sizeof(*status))
> +               return -EINVAL;
> +
> +       in = (struct scmi_base_set_protocol_permissions_in *)msg->in_msg;
> +       status = (u32 *)msg->out_msg;
> +
> +       for (i = 0; i < ARRAY_SIZE(protocols); i++)
> +               if (protocols[i] == in->command_id)
> +                       break;
> +       if (in->agent_id != 1 || in->device_id != 0 ||
> +           i == ARRAY_SIZE(protocols))
> +               *status = SCMI_NOT_FOUND;
> +       else if (in->flags & ~SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
> +               *status = SCMI_INVALID_PARAMETERS;
> +       else if (in->flags & SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
> +               *status = SCMI_SUCCESS;
> +       else
> +               /* unset not allowed */
> +               *status = SCMI_DENIED;
> +
> +       return 0;
> +}
> +
> +/**
> + * sandbox_scmi_base_reset_agent_configuration - implement
> + *                                     SCMI_BASE_RESET_AGENT_CONFIGURATION
> + * @udevice:   SCMI device
> + * @msg:       SCMI message
> + *
> + * Implement SCMI_BASE_RESET_AGENT_CONFIGURATION command
> + */
> +static int sandbox_scmi_base_reset_agent_configuration(struct udevice *dev,
> +                                                      struct scmi_msg *msg)
> +{
> +       struct scmi_base_reset_agent_configuration_in *in = NULL;
> +       u32 *status;
> +
> +       if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
> +           !msg->out_msg || msg->out_msg_sz < sizeof(*status))
> +               return -EINVAL;
> +
> +       in = (struct scmi_base_reset_agent_configuration_in *)msg->in_msg;
> +       status = (u32 *)msg->out_msg;
> +
> +       if (in->agent_id != 1)
> +               *status = SCMI_NOT_FOUND;
> +       else if (in->flags & ~SCMI_BASE_RESET_ALL_ACCESS_PERMISSIONS)
> +               *status = SCMI_INVALID_PARAMETERS;
> +       else
> +               *status = SCMI_DENIED;
> +
> +       return 0;
> +}
> +
> +/* Clock Protocol */
> +
>  static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
>                                                 struct scmi_msg *msg)
>  {
> @@ -475,6 +803,36 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
>                                           struct scmi_msg *msg)
>  {
>          switch (msg->protocol_id) {
> +       case SCMI_PROTOCOL_ID_BASE:
> +               switch (msg->message_id) {
> +               case SCMI_PROTOCOL_VERSION:
> +                       return sandbox_scmi_base_protocol_version(dev, msg);
> +               case SCMI_PROTOCOL_ATTRIBUTES:
> +                       return sandbox_scmi_base_protocol_attrs(dev, msg);
> +               case SCMI_PROTOCOL_MESSAGE_ATTRIBUTES:
> +                       return sandbox_scmi_base_message_attrs(dev, msg);
> +               case SCMI_BASE_DISCOVER_VENDOR:
> +                       return sandbox_scmi_base_discover_vendor(dev, msg);
> +               case SCMI_BASE_DISCOVER_SUB_VENDOR:
> +                       return sandbox_scmi_base_discover_sub_vendor(dev, msg);
> +               case SCMI_BASE_DISCOVER_IMPL_VERSION:
> +                       return sandbox_scmi_base_discover_impl_version(dev, msg);
> +               case SCMI_BASE_DISCOVER_LIST_PROTOCOLS:
> +                       return sandbox_scmi_base_discover_list_protocols(dev, msg);
> +               case SCMI_BASE_DISCOVER_AGENT:
> +                       return sandbox_scmi_base_discover_agent(dev, msg);
> +               case SCMI_BASE_NOTIFY_ERRORS:
> +                       break;
> +               case SCMI_BASE_SET_DEVICE_PERMISSIONS:
> +                       return sandbox_scmi_base_set_device_permissions(dev, msg);
> +               case SCMI_BASE_SET_PROTOCOL_PERMISSIONS:
> +                       return sandbox_scmi_base_set_protocol_permissions(dev, msg);
> +               case SCMI_BASE_RESET_AGENT_CONFIGURATION:
> +                       return sandbox_scmi_base_reset_agent_configuration(dev, msg);
> +               default:
> +                       break;
> +               }
> +               break;
>          case SCMI_PROTOCOL_ID_CLOCK:
>                  switch (msg->message_id) {
>                  case SCMI_PROTOCOL_ATTRIBUTES:
> @@ -517,7 +875,6 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
>                          break;
>                  }
>                  break;
> -       case SCMI_PROTOCOL_ID_BASE:
>          case SCMI_PROTOCOL_ID_POWER_DOMAIN:
>          case SCMI_PROTOCOL_ID_SYSTEM:
>          case SCMI_PROTOCOL_ID_PERF:
> -- 
> 2.41.0
>
diff mbox series

Patch

diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 031882998dfa..1f0261ea5c94 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -14,11 +14,14 @@ 
 #include <asm/io.h>
 #include <asm/scmi_test.h>
 #include <dm/device_compat.h>
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
 
 /*
  * The sandbox SCMI agent driver simulates to some extend a SCMI message
  * processing. It simulates few of the SCMI services for some of the
  * SCMI protocols embedded in U-Boot. Currently:
+ * - SCMI base protocol
  * - SCMI clock protocol emulates an agent exposing 2 clocks
  * - SCMI reset protocol emulates an agent exposing a reset controller
  * - SCMI voltage domain protocol emulates an agent exposing 2 regulators
@@ -33,6 +36,21 @@ 
  * various uclass devices, as clocks and reset controllers.
  */
 
+#define SANDBOX_SCMI_BASE_PROTOCOL_VERSION SCMI_BASE_PROTOCOL_VERSION
+#define SANDBOX_SCMI_VENDOR "U-Boot"
+#define SANDBOX_SCMI_SUB_VENDOR "Sandbox"
+#define SANDBOX_SCMI_IMPL_VERSION 0x1
+#define SANDBOX_SCMI_AGENT_NAME "OSPM"
+#define SANDBOX_SCMI_PLATFORM_NAME "platform"
+
+static u8 protocols[] = {
+	SCMI_PROTOCOL_ID_CLOCK,
+	SCMI_PROTOCOL_ID_RESET_DOMAIN,
+	SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
+};
+
+#define NUM_PROTOCOLS ARRAY_SIZE(protocols)
+
 static struct sandbox_scmi_clk scmi_clk[] = {
 	{ .rate = 333 },
 	{ .rate = 200 },
@@ -114,6 +132,316 @@  static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint domain_id)
  * Sandbox SCMI agent ops
  */
 
+/* Base Protocol */
+
+/**
+ * sandbox_scmi_base_protocol_version - implement SCMI_BASE_PROTOCOL_VERSION
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_PROTOCOL_VERSION command.
+ */
+static int sandbox_scmi_base_protocol_version(struct udevice *dev,
+					      struct scmi_msg *msg)
+{
+	struct scmi_protocol_version_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_protocol_version_out *)msg->out_msg;
+	out->version = SANDBOX_SCMI_BASE_PROTOCOL_VERSION;
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_protocol_attrs - implement SCMI_BASE_PROTOCOL_ATTRIBUTES
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_PROTOCOL_ATTRIBUTES command.
+ */
+static int sandbox_scmi_base_protocol_attrs(struct udevice *dev,
+					    struct scmi_msg *msg)
+{
+	struct scmi_protocol_attrs_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_protocol_attrs_out *)msg->out_msg;
+	out->attributes = FIELD_PREP(0xff00, 2) | NUM_PROTOCOLS;
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_message_attrs - implement
+ *					SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES command.
+ */
+static int sandbox_scmi_base_message_attrs(struct udevice *dev,
+					   struct scmi_msg *msg)
+{
+	u32 message_id;
+	struct scmi_protocol_msg_attrs_out *out = NULL;
+
+	if (!msg->in_msg || msg->in_msg_sz < sizeof(message_id) ||
+	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	message_id = *(u32 *)msg->in_msg;
+	out = (struct scmi_protocol_msg_attrs_out *)msg->out_msg;
+
+	if (message_id >= SCMI_PROTOCOL_VERSION &&
+	    message_id <= SCMI_BASE_RESET_AGENT_CONFIGURATION &&
+	    message_id != SCMI_BASE_NOTIFY_ERRORS) {
+		out->attributes = 0;
+		out->status = SCMI_SUCCESS;
+	} else {
+		out->status = SCMI_NOT_FOUND;
+	}
+
+		return 0;
+}
+
+/**
+ * sandbox_scmi_base_discover_vendor - implement SCMI_BASE_DISCOVER_VENDOR
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_DISCOVER_VENDOR command
+ */
+static int sandbox_scmi_base_discover_vendor(struct udevice *dev,
+					     struct scmi_msg *msg)
+{
+	struct scmi_base_discover_vendor_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
+	strcpy(out->vendor_identifier, SANDBOX_SCMI_VENDOR);
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_discover_sub_vendor - implement
+ *						SCMI_BASE_DISCOVER_SUB_VENDOR
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_DISCOVER_SUB_VENDOR command
+ */
+static int sandbox_scmi_base_discover_sub_vendor(struct udevice *dev,
+						 struct scmi_msg *msg)
+{
+	struct scmi_base_discover_vendor_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
+	strcpy(out->vendor_identifier, SANDBOX_SCMI_SUB_VENDOR);
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_discover_impl_version - implement
+ *				SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION command
+ */
+static int sandbox_scmi_base_discover_impl_version(struct udevice *dev,
+						   struct scmi_msg *msg)
+{
+	struct scmi_base_discover_impl_version_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_base_discover_impl_version_out *)msg->out_msg;
+	out->impl_version = SANDBOX_SCMI_IMPL_VERSION;
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_discover_list_protocols - implement
+ *					SCMI_BASE_DISCOVER_LIST_PROTOCOLS
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_DISCOVER_LIST_PROTOCOLS command
+ */
+static int sandbox_scmi_base_discover_list_protocols(struct udevice *dev,
+						     struct scmi_msg *msg)
+{
+	struct scmi_base_discover_list_protocols_out *out = NULL;
+
+	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	out = (struct scmi_base_discover_list_protocols_out *)msg->out_msg;
+	memcpy(out->protocols, protocols, sizeof(protocols));
+	out->num_protocols = NUM_PROTOCOLS;
+	out->status = SCMI_SUCCESS;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_discover_agent - implement SCMI_BASE_DISCOVER_AGENT
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_DISCOVER_AGENT command
+ */
+static int sandbox_scmi_base_discover_agent(struct udevice *dev,
+					    struct scmi_msg *msg)
+{
+	u32 agent_id;
+	struct scmi_base_discover_agent_out *out = NULL;
+
+	if (!msg->in_msg || msg->in_msg_sz < sizeof(agent_id) ||
+	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+		return -EINVAL;
+
+	agent_id = *(u32 *)msg->in_msg;
+	out = (struct scmi_base_discover_agent_out *)msg->out_msg;
+	out->status = SCMI_SUCCESS;
+	if (agent_id == 0xffffffff || agent_id == 1) {
+		out->agent_id = 1;
+		strcpy(out->name, SANDBOX_SCMI_AGENT_NAME);
+	} else if (!agent_id) {
+		out->agent_id = agent_id;
+		strcpy(out->name, SANDBOX_SCMI_PLATFORM_NAME);
+	} else {
+		out->status = SCMI_NOT_FOUND;
+	}
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_set_device_permissions - implement
+ *						SCMI_BASE_SET_DEVICE_PERMISSIONS
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_SET_DEVICE_PERMISSIONS command
+ */
+static int sandbox_scmi_base_set_device_permissions(struct udevice *dev,
+						    struct scmi_msg *msg)
+{
+	struct scmi_base_set_device_permissions_in *in = NULL;
+	u32 *status;
+
+	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
+		return -EINVAL;
+
+	in = (struct scmi_base_set_device_permissions_in *)msg->in_msg;
+	status = (u32 *)msg->out_msg;
+
+	if (in->agent_id != 1 || in->device_id != 0)
+		*status = SCMI_NOT_FOUND;
+	else if (in->flags & ~SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
+		*status = SCMI_INVALID_PARAMETERS;
+	else if (in->flags & SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
+		*status = SCMI_SUCCESS;
+	else
+		/* unset not allowed */
+		*status = SCMI_DENIED;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_set_protocol_permissions - implement
+ *					SCMI_BASE_SET_PROTOCOL_PERMISSIONS
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_SET_PROTOCOL_PERMISSIONS command
+ */
+static int sandbox_scmi_base_set_protocol_permissions(struct udevice *dev,
+						      struct scmi_msg *msg)
+{
+	struct scmi_base_set_protocol_permissions_in *in = NULL;
+	u32 *status;
+	int i;
+
+	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
+		return -EINVAL;
+
+	in = (struct scmi_base_set_protocol_permissions_in *)msg->in_msg;
+	status = (u32 *)msg->out_msg;
+
+	for (i = 0; i < ARRAY_SIZE(protocols); i++)
+		if (protocols[i] == in->command_id)
+			break;
+	if (in->agent_id != 1 || in->device_id != 0 ||
+	    i == ARRAY_SIZE(protocols))
+		*status = SCMI_NOT_FOUND;
+	else if (in->flags & ~SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
+		*status = SCMI_INVALID_PARAMETERS;
+	else if (in->flags & SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
+		*status = SCMI_SUCCESS;
+	else
+		/* unset not allowed */
+		*status = SCMI_DENIED;
+
+	return 0;
+}
+
+/**
+ * sandbox_scmi_base_reset_agent_configuration - implement
+ *					SCMI_BASE_RESET_AGENT_CONFIGURATION
+ * @udevice:	SCMI device
+ * @msg:	SCMI message
+ *
+ * Implement SCMI_BASE_RESET_AGENT_CONFIGURATION command
+ */
+static int sandbox_scmi_base_reset_agent_configuration(struct udevice *dev,
+						       struct scmi_msg *msg)
+{
+	struct scmi_base_reset_agent_configuration_in *in = NULL;
+	u32 *status;
+
+	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
+		return -EINVAL;
+
+	in = (struct scmi_base_reset_agent_configuration_in *)msg->in_msg;
+	status = (u32 *)msg->out_msg;
+
+	if (in->agent_id != 1)
+		*status = SCMI_NOT_FOUND;
+	else if (in->flags & ~SCMI_BASE_RESET_ALL_ACCESS_PERMISSIONS)
+		*status = SCMI_INVALID_PARAMETERS;
+	else
+		*status = SCMI_DENIED;
+
+	return 0;
+}
+
+/* Clock Protocol */
+
 static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
 					       struct scmi_msg *msg)
 {
@@ -475,6 +803,36 @@  static int sandbox_scmi_test_process_msg(struct udevice *dev,
 					 struct scmi_msg *msg)
 {
 	switch (msg->protocol_id) {
+	case SCMI_PROTOCOL_ID_BASE:
+		switch (msg->message_id) {
+		case SCMI_PROTOCOL_VERSION:
+			return sandbox_scmi_base_protocol_version(dev, msg);
+		case SCMI_PROTOCOL_ATTRIBUTES:
+			return sandbox_scmi_base_protocol_attrs(dev, msg);
+		case SCMI_PROTOCOL_MESSAGE_ATTRIBUTES:
+			return sandbox_scmi_base_message_attrs(dev, msg);
+		case SCMI_BASE_DISCOVER_VENDOR:
+			return sandbox_scmi_base_discover_vendor(dev, msg);
+		case SCMI_BASE_DISCOVER_SUB_VENDOR:
+			return sandbox_scmi_base_discover_sub_vendor(dev, msg);
+		case SCMI_BASE_DISCOVER_IMPL_VERSION:
+			return sandbox_scmi_base_discover_impl_version(dev, msg);
+		case SCMI_BASE_DISCOVER_LIST_PROTOCOLS:
+			return sandbox_scmi_base_discover_list_protocols(dev, msg);
+		case SCMI_BASE_DISCOVER_AGENT:
+			return sandbox_scmi_base_discover_agent(dev, msg);
+		case SCMI_BASE_NOTIFY_ERRORS:
+			break;
+		case SCMI_BASE_SET_DEVICE_PERMISSIONS:
+			return sandbox_scmi_base_set_device_permissions(dev, msg);
+		case SCMI_BASE_SET_PROTOCOL_PERMISSIONS:
+			return sandbox_scmi_base_set_protocol_permissions(dev, msg);
+		case SCMI_BASE_RESET_AGENT_CONFIGURATION:
+			return sandbox_scmi_base_reset_agent_configuration(dev, msg);
+		default:
+			break;
+		}
+		break;
 	case SCMI_PROTOCOL_ID_CLOCK:
 		switch (msg->message_id) {
 		case SCMI_PROTOCOL_ATTRIBUTES:
@@ -517,7 +875,6 @@  static int sandbox_scmi_test_process_msg(struct udevice *dev,
 			break;
 		}
 		break;
-	case SCMI_PROTOCOL_ID_BASE:
 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
 	case SCMI_PROTOCOL_ID_SYSTEM:
 	case SCMI_PROTOCOL_ID_PERF: