blob: 8542150ba5b633baf4653a50fe95c1ce2852f5a4 [file] [log] [blame]
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +00001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +00008#include <debug.h>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +00009#include <drivers/console.h>
10#include <drivers/arm/pl011.h>
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +000011#include <errno.h>
12#include <ivy_def.h>
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +000013#include <plat_arm.h>
14#include <platform_def.h>
Antonio Nino Diaz2ac6f8f2018-07-02 09:04:07 +010015#include <sp_helpers.h>
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +000016#include <sprt_client.h>
17#include <sprt_svc.h>
18
19#include "ivy.h"
20#include "ivy_def.h"
21
22/* Host machine information injected by the build system in the ELF file. */
23extern const char build_message[];
24extern const char version_string[];
25
26static void ivy_print_memory_layout(void)
27{
28 NOTICE("Secure Partition memory layout:\n");
29
30 NOTICE(" Image regions\n");
31 NOTICE(" Text region : %p - %p\n",
32 (void *)IVY_TEXT_START, (void *)IVY_TEXT_END);
33 NOTICE(" Read-only data region : %p - %p\n",
34 (void *)IVY_RODATA_START, (void *)IVY_RODATA_END);
35 NOTICE(" Data region : %p - %p\n",
36 (void *)IVY_DATA_START, (void *)IVY_DATA_END);
37 NOTICE(" BSS region : %p - %p\n",
38 (void *)IVY_BSS_START, (void *)IVY_BSS_END);
39 NOTICE(" Total image memory : %p - %p\n",
40 (void *)IVY_IMAGE_BASE,
41 (void *)(IVY_IMAGE_BASE + IVY_IMAGE_SIZE));
42 NOTICE(" SPM regions\n");
43 NOTICE(" SPM <-> SP buffer : %p - %p\n",
44 (void *)IVY_SPM_BUF_BASE,
45 (void *)(IVY_SPM_BUF_BASE + IVY_SPM_BUF_SIZE));
46 NOTICE(" NS <-> SP buffer : %p - %p\n",
47 (void *)IVY_NS_BUF_BASE,
48 (void *)(IVY_NS_BUF_BASE + IVY_NS_BUF_SIZE));
49}
50
51void ivy_message_handler(struct sprt_queue_entry_message *message)
52{
53 u_register_t ret0 = 0U, ret1 = 0U, ret2 = 0U, ret3 = 0U;
54
55 if (message->type == SPRT_MSG_TYPE_SERVICE_REQUEST) {
56 switch (message->args[1]) {
57
58 case IVY_PRINT_MAGIC:
59 INFO("IVY: Magic: 0x%x\n", IVY_MAGIC_NUMBER);
60 ret0 = SPRT_SUCCESS;
61 break;
62
63 case IVY_GET_MAGIC:
64 ret1 = IVY_MAGIC_NUMBER;
65 ret0 = SPRT_SUCCESS;
66 break;
67
Antonio Nino Diaz2ac6f8f2018-07-02 09:04:07 +010068 case IVY_SLEEP_MS:
69 sp_sleep(message->args[2]);
70 ret0 = SPRT_SUCCESS;
71 break;
72
Antonio Nino Diaz0b1ab402018-12-05 15:38:39 +000073 default:
74 NOTICE("IVY: Unhandled Service ID 0x%x\n",
75 (unsigned int)message->args[1]);
76 ret0 = SPRT_NOT_SUPPORTED;
77 break;
78 }
79 } else {
80 NOTICE("Ivy: Unhandled Service type 0x%x\n",
81 (unsigned int)message->type);
82 ret0 = SPRT_NOT_SUPPORTED;
83 }
84
85
86 sprt_message_end(message, ret0, ret1, ret2, ret3);
87}
88
89void __dead2 ivy_main(void)
90{
91 console_init(PL011_UART3_BASE,
92 PL011_UART3_CLK_IN_HZ,
93 PL011_BAUDRATE);
94
95 NOTICE("Booting test Secure Partition Ivy\n");
96 NOTICE("%s\n", build_message);
97 NOTICE("%s\n", version_string);
98 NOTICE("Running at S-EL0\n");
99
100 ivy_print_memory_layout();
101
102 /*
103 * Handle secure service requests.
104 */
105 sprt_initialize_queues((void *)IVY_SPM_BUF_BASE);
106
107 while (1) {
108 struct sprt_queue_entry_message message;
109
110 /*
111 * Try to fetch a message from the blocking requests queue. If
112 * it is empty, try to fetch from the non-blocking requests
113 * queue. Repeat until both of them are empty.
114 */
115 while (1) {
116 int err = sprt_get_next_message(&message,
117 SPRT_QUEUE_NUM_BLOCKING);
118 if (err == -ENOENT) {
119 err = sprt_get_next_message(&message,
120 SPRT_QUEUE_NUM_NON_BLOCKING);
121 if (err == -ENOENT) {
122 break;
123 } else {
124 assert(err == 0);
125 ivy_message_handler(&message);
126 }
127 } else {
128 assert(err == 0);
129 ivy_message_handler(&message);
130 }
131 }
132
133 sprt_wait_for_messages();
134 }
135}