Contiki-NG
Loading...
Searching...
No Matches
tz-api.c
1/*
2 * Copyright (c) 2023, RISE Research Institutes of Sweden
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Authors: Niclas Finne <niclas.finne@ri.se>
36 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
37 */
38
39#include "contiki.h"
40#include "sys/autostart.h"
41#include "tz-api.h"
42
43#include <arm_cmse.h>
44#include <stdarg.h>
45#include <string.h>
46
47static struct tz_api tz_api;
48static bool initialized;
49static volatile bool ns_poll_pending;
50
51/*---------------------------------------------------------------------------*/
52#include "sys/log.h"
53#define LOG_MODULE "TZAPI"
54#define LOG_LEVEL LOG_LEVEL_INFO
55/*---------------------------------------------------------------------------*/
56process_event_t trustzone_init_event;
57/*---------------------------------------------------------------------------*/
58CC_TRUSTZONE_SECURE_CALL bool
59tz_api_init(struct tz_api *apip)
60{
61 if(initialized || apip == NULL) {
62 return false;
63 }
64
65 apip = cmse_check_address_range(apip, sizeof(*apip), CMSE_NONSECURE);
66 if(apip == NULL || apip->request_poll == NULL) {
67 return false;
68 }
69
70 ns_poll_t poll_fn = cmse_nsfptr_create(apip->request_poll);
71 if(!cmse_is_nsfptr(poll_fn)) {
72 return false;
73 }
74
75 trustzone_init_event = process_alloc_event();
76 tz_api.request_poll = poll_fn;
77
78 initialized = true;
79
80 for(size_t i = 0; autostart_processes[i] != NULL; i++) {
81 process_post(autostart_processes[i], trustzone_init_event, NULL);
82 }
83
84 return true;
85}
86/*---------------------------------------------------------------------------*/
87CC_TRUSTZONE_SECURE_CALL bool
89{
90 static bool is_poll_running;
91
92 /*
93 * tz_api_poll() runs process_run() and is not reentrant. Per the
94 * contract in tz-api.h it must be called only from NS thread mode.
95 * Reject handler-mode callers (NS interrupt or, defensively, a
96 * secure ISR) up front so the API fails closed instead of
97 * corrupting the event loop. IPSR is preserved across the SG
98 * transition, so it reflects the NS caller's mode.
99 */
100 if(__get_IPSR() != 0) {
101 return false;
102 }
103 if(!initialized || is_poll_running) {
104 return false;
105 }
106 is_poll_running = true;
107
108 /*
109 * Clear ns_poll_pending before draining the queue so that any
110 * secure ISR that fires during or after the loop is captured by
111 * the final read below. The NS caller reschedules itself when we
112 * return true, so no cross-boundary callback is needed here.
113 */
114 ns_poll_pending = false;
115
116 process_num_events_t event_count = process_nevents();
117
118 if(event_count > 0) {
119 LOG_DBG("Processing %u event%s at %" CLOCK_PRI "\n", event_count,
120 event_count == 1 ? "" : "s", clock_time());
121 }
122
123 while(event_count-- > 0) {
124 process_run();
126 }
127
128 is_poll_running = false;
129
130 return ns_poll_pending || process_nevents() > 0;
131}
132/*---------------------------------------------------------------------------*/
133#define TZ_API_PRINTLN_MAX_LEN 256
134
135CC_TRUSTZONE_SECURE_CALL void
136tz_api_println(const char *text, size_t len)
137{
138 if(len > TZ_API_PRINTLN_MAX_LEN) {
139 len = TZ_API_PRINTLN_MAX_LEN;
140 }
141 if(text == NULL || len == 0 ||
142 cmse_check_address_range((void *)text, len,
143 CMSE_NONSECURE) == NULL) {
144 return;
145 }
146 printf("n> %.*s\n", (int)len, text);
147}
148/*---------------------------------------------------------------------------*/
149__attribute__((weak)) void
150tz_arch_signal_ns(void)
151{
152}
153/*---------------------------------------------------------------------------*/
154bool
156{
157 if(!initialized) {
158 return false;
159 }
160 ns_poll_pending = true;
161 tz_arch_signal_ns();
162 return true;
163}
164/*---------------------------------------------------------------------------*/
Header file for module for automatically starting and exiting a list of processes.
clock_time_t clock_time(void)
Get the current clock time.
Definition clock.c:118
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition watchdog.c:85
process_num_events_t process_run(void)
Run the system once - call poll handlers and process one event.
Definition process.c:305
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition process.c:325
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition process.c:111
process_num_events_t process_nevents(void)
Number of events waiting to be processed.
Definition process.c:319
void tz_api_println(const char *text, size_t len)
Print the specified message via the secure world.
Definition tz-api.c:136
bool tz_api_request_ns_poll(void)
Mark the normal world as needing another poll cycle.
Definition tz-api.c:155
bool tz_api_init(struct tz_api *apip)
Initialize the TrustZone API.
Definition tz-api.c:59
bool tz_api_poll(void)
Poll the secure world and process all events in the queue.
Definition tz-api.c:88
Header file for the logging system.