ivy: Introduce new test Secure Partition
In order to test multiple partitions it is needed to have at least two
different partitions with different services. This way it isn't possible
to accidentally call partition A with a service of partition B and have
it work correctly.
Cactus is meant to be the main test Secure Partition. It is the one
meant to have most of the tests that a Secure Partition has to do. Ivy
is meant to be more minimalistic. In the future, Cactus may be modified
to be a S-EL1 partition while Ivy will remain as a S-EL0 partition.
Change-Id: I29d09b9f9400b58568f9b90344a4034332a6e6e1
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
diff --git a/spm/ivy/ivy_main.c b/spm/ivy/ivy_main.c
new file mode 100644
index 0000000..cd81e88
--- /dev/null
+++ b/spm/ivy/ivy_main.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <ivy_def.h>
+#include <pl011.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sprt_client.h>
+#include <sprt_svc.h>
+
+#include "ivy.h"
+#include "ivy_def.h"
+
+/* Host machine information injected by the build system in the ELF file. */
+extern const char build_message[];
+extern const char version_string[];
+
+static void ivy_print_memory_layout(void)
+{
+ NOTICE("Secure Partition memory layout:\n");
+
+ NOTICE(" Image regions\n");
+ NOTICE(" Text region : %p - %p\n",
+ (void *)IVY_TEXT_START, (void *)IVY_TEXT_END);
+ NOTICE(" Read-only data region : %p - %p\n",
+ (void *)IVY_RODATA_START, (void *)IVY_RODATA_END);
+ NOTICE(" Data region : %p - %p\n",
+ (void *)IVY_DATA_START, (void *)IVY_DATA_END);
+ NOTICE(" BSS region : %p - %p\n",
+ (void *)IVY_BSS_START, (void *)IVY_BSS_END);
+ NOTICE(" Total image memory : %p - %p\n",
+ (void *)IVY_IMAGE_BASE,
+ (void *)(IVY_IMAGE_BASE + IVY_IMAGE_SIZE));
+ NOTICE(" SPM regions\n");
+ NOTICE(" SPM <-> SP buffer : %p - %p\n",
+ (void *)IVY_SPM_BUF_BASE,
+ (void *)(IVY_SPM_BUF_BASE + IVY_SPM_BUF_SIZE));
+ NOTICE(" NS <-> SP buffer : %p - %p\n",
+ (void *)IVY_NS_BUF_BASE,
+ (void *)(IVY_NS_BUF_BASE + IVY_NS_BUF_SIZE));
+}
+
+void ivy_message_handler(struct sprt_queue_entry_message *message)
+{
+ u_register_t ret0 = 0U, ret1 = 0U, ret2 = 0U, ret3 = 0U;
+
+ if (message->type == SPRT_MSG_TYPE_SERVICE_REQUEST) {
+ switch (message->args[1]) {
+
+ case IVY_PRINT_MAGIC:
+ INFO("IVY: Magic: 0x%x\n", IVY_MAGIC_NUMBER);
+ ret0 = SPRT_SUCCESS;
+ break;
+
+ case IVY_GET_MAGIC:
+ ret1 = IVY_MAGIC_NUMBER;
+ ret0 = SPRT_SUCCESS;
+ break;
+
+ default:
+ NOTICE("IVY: Unhandled Service ID 0x%x\n",
+ (unsigned int)message->args[1]);
+ ret0 = SPRT_NOT_SUPPORTED;
+ break;
+ }
+ } else {
+ NOTICE("Ivy: Unhandled Service type 0x%x\n",
+ (unsigned int)message->type);
+ ret0 = SPRT_NOT_SUPPORTED;
+ }
+
+
+ sprt_message_end(message, ret0, ret1, ret2, ret3);
+}
+
+void __dead2 ivy_main(void)
+{
+ console_init(PL011_UART3_BASE,
+ PL011_UART3_CLK_IN_HZ,
+ PL011_BAUDRATE);
+
+ NOTICE("Booting test Secure Partition Ivy\n");
+ NOTICE("%s\n", build_message);
+ NOTICE("%s\n", version_string);
+ NOTICE("Running at S-EL0\n");
+
+ ivy_print_memory_layout();
+
+ /*
+ * Handle secure service requests.
+ */
+ sprt_initialize_queues((void *)IVY_SPM_BUF_BASE);
+
+ while (1) {
+ struct sprt_queue_entry_message message;
+
+ /*
+ * Try to fetch a message from the blocking requests queue. If
+ * it is empty, try to fetch from the non-blocking requests
+ * queue. Repeat until both of them are empty.
+ */
+ while (1) {
+ int err = sprt_get_next_message(&message,
+ SPRT_QUEUE_NUM_BLOCKING);
+ if (err == -ENOENT) {
+ err = sprt_get_next_message(&message,
+ SPRT_QUEUE_NUM_NON_BLOCKING);
+ if (err == -ENOENT) {
+ break;
+ } else {
+ assert(err == 0);
+ ivy_message_handler(&message);
+ }
+ } else {
+ assert(err == 0);
+ ivy_message_handler(&message);
+ }
+ }
+
+ sprt_wait_for_messages();
+ }
+}