1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2019, Google, Inc. All rights reserved
3*344aa361SAndroid Build Coastguard Worker *
4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker *
12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker *
15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker */
23*344aa361SAndroid Build Coastguard Worker #include <assert.h>
24*344aa361SAndroid Build Coastguard Worker #include <err.h>
25*344aa361SAndroid Build Coastguard Worker #include <kernel/timer.h>
26*344aa361SAndroid Build Coastguard Worker #include <lk/init.h>
27*344aa361SAndroid Build Coastguard Worker #include <platform.h>
28*344aa361SAndroid Build Coastguard Worker #include <trace.h>
29*344aa361SAndroid Build Coastguard Worker
30*344aa361SAndroid Build Coastguard Worker #include <lib/trusty/event.h>
31*344aa361SAndroid Build Coastguard Worker #include <lib/trusty/uirq.h>
32*344aa361SAndroid Build Coastguard Worker #include <lib/trusty/uuid.h>
33*344aa361SAndroid Build Coastguard Worker
34*344aa361SAndroid Build Coastguard Worker #define LOCAL_TRACE 0
35*344aa361SAndroid Build Coastguard Worker
36*344aa361SAndroid Build Coastguard Worker #define MS_TO_NS(ms) ((ms)*1000ULL * 1000ULL)
37*344aa361SAndroid Build Coastguard Worker
38*344aa361SAndroid Build Coastguard Worker struct timer_uirq {
39*344aa361SAndroid Build Coastguard Worker struct uirq uirq;
40*344aa361SAndroid Build Coastguard Worker struct timer tm;
41*344aa361SAndroid Build Coastguard Worker struct handle* handle;
42*344aa361SAndroid Build Coastguard Worker lk_time_ns_t delay;
43*344aa361SAndroid Build Coastguard Worker };
44*344aa361SAndroid Build Coastguard Worker
45*344aa361SAndroid Build Coastguard Worker static const struct uuid _test_app_uuid[] = {
46*344aa361SAndroid Build Coastguard Worker /* UIRQ unittest app UUID : {e20af937-a4d0-4b95-b852-95ef21333cd1} */
47*344aa361SAndroid Build Coastguard Worker {0xe20af937,
48*344aa361SAndroid Build Coastguard Worker 0xa4d0,
49*344aa361SAndroid Build Coastguard Worker 0x4b95,
50*344aa361SAndroid Build Coastguard Worker {0xb8, 0x52, 0x95, 0xef, 0x21, 0x33, 0x3c, 0xd1}},
51*344aa361SAndroid Build Coastguard Worker };
52*344aa361SAndroid Build Coastguard Worker
53*344aa361SAndroid Build Coastguard Worker static struct timer_uirq _tm_uirqs[] = {
54*344aa361SAndroid Build Coastguard Worker {
55*344aa361SAndroid Build Coastguard Worker .uirq = UIRQ_INITIALIZER("test-uirq-10ms",
56*344aa361SAndroid Build Coastguard Worker &_test_app_uuid[0],
57*344aa361SAndroid Build Coastguard Worker 1,
58*344aa361SAndroid Build Coastguard Worker 0),
59*344aa361SAndroid Build Coastguard Worker .tm = TIMER_INITIAL_VALUE(.tm),
60*344aa361SAndroid Build Coastguard Worker .delay = MS_TO_NS(10),
61*344aa361SAndroid Build Coastguard Worker },
62*344aa361SAndroid Build Coastguard Worker {
63*344aa361SAndroid Build Coastguard Worker .uirq = UIRQ_INITIALIZER("test-uirq-no-access",
64*344aa361SAndroid Build Coastguard Worker &zero_uuid,
65*344aa361SAndroid Build Coastguard Worker 1,
66*344aa361SAndroid Build Coastguard Worker 0),
67*344aa361SAndroid Build Coastguard Worker .tm = TIMER_INITIAL_VALUE(.tm),
68*344aa361SAndroid Build Coastguard Worker .delay = MS_TO_NS(50),
69*344aa361SAndroid Build Coastguard Worker },
70*344aa361SAndroid Build Coastguard Worker };
71*344aa361SAndroid Build Coastguard Worker
72*344aa361SAndroid Build Coastguard Worker static lk_time_ns_t ts_start;
73*344aa361SAndroid Build Coastguard Worker static lk_time_ns_t ts_notified;
74*344aa361SAndroid Build Coastguard Worker static lk_time_ns_t ts_handled;
75*344aa361SAndroid Build Coastguard Worker static lk_time_ns_t ttl_elapsed1;
76*344aa361SAndroid Build Coastguard Worker static lk_time_ns_t ttl_elapsed2;
77*344aa361SAndroid Build Coastguard Worker static unsigned int ttl_count;
78*344aa361SAndroid Build Coastguard Worker
test_tm_uirq_callback(struct timer * t,lk_time_ns_t now,void * arg)79*344aa361SAndroid Build Coastguard Worker static enum handler_return test_tm_uirq_callback(struct timer* t,
80*344aa361SAndroid Build Coastguard Worker lk_time_ns_t now,
81*344aa361SAndroid Build Coastguard Worker void* arg) {
82*344aa361SAndroid Build Coastguard Worker struct timer_uirq* u = arg;
83*344aa361SAndroid Build Coastguard Worker ts_start = current_time_ns();
84*344aa361SAndroid Build Coastguard Worker event_source_signal(u->handle);
85*344aa361SAndroid Build Coastguard Worker ts_notified = current_time_ns();
86*344aa361SAndroid Build Coastguard Worker return INT_RESCHEDULE;
87*344aa361SAndroid Build Coastguard Worker };
88*344aa361SAndroid Build Coastguard Worker
tm_uirq_mask(const void * arg)89*344aa361SAndroid Build Coastguard Worker static void tm_uirq_mask(const void* arg) {}
90*344aa361SAndroid Build Coastguard Worker
tm_uirq_unmask(const void * arg)91*344aa361SAndroid Build Coastguard Worker static void tm_uirq_unmask(const void* arg) {
92*344aa361SAndroid Build Coastguard Worker ts_handled = current_time_ns();
93*344aa361SAndroid Build Coastguard Worker if (ts_start) {
94*344aa361SAndroid Build Coastguard Worker ttl_elapsed1 += ts_notified - ts_start;
95*344aa361SAndroid Build Coastguard Worker ttl_elapsed2 += ts_handled - ts_start;
96*344aa361SAndroid Build Coastguard Worker ttl_count++;
97*344aa361SAndroid Build Coastguard Worker ts_start = 0;
98*344aa361SAndroid Build Coastguard Worker }
99*344aa361SAndroid Build Coastguard Worker struct timer_uirq* u = (struct timer_uirq*)arg;
100*344aa361SAndroid Build Coastguard Worker timer_set_oneshot_ns(&u->tm, u->delay, test_tm_uirq_callback, u);
101*344aa361SAndroid Build Coastguard Worker }
102*344aa361SAndroid Build Coastguard Worker
tm_uirq_open(const void * arg)103*344aa361SAndroid Build Coastguard Worker static void tm_uirq_open(const void* arg) {
104*344aa361SAndroid Build Coastguard Worker ttl_count = 0;
105*344aa361SAndroid Build Coastguard Worker ts_start = 0;
106*344aa361SAndroid Build Coastguard Worker ts_notified = 0;
107*344aa361SAndroid Build Coastguard Worker ts_handled = 0;
108*344aa361SAndroid Build Coastguard Worker ttl_elapsed1 = 0;
109*344aa361SAndroid Build Coastguard Worker ttl_elapsed2 = 0;
110*344aa361SAndroid Build Coastguard Worker
111*344aa361SAndroid Build Coastguard Worker struct timer_uirq* u = (struct timer_uirq*)arg;
112*344aa361SAndroid Build Coastguard Worker timer_set_oneshot_ns(&u->tm, u->delay, test_tm_uirq_callback, u);
113*344aa361SAndroid Build Coastguard Worker }
114*344aa361SAndroid Build Coastguard Worker
tm_uirq_close(const void * arg)115*344aa361SAndroid Build Coastguard Worker static void tm_uirq_close(const void* arg) {
116*344aa361SAndroid Build Coastguard Worker struct timer_uirq* u = (struct timer_uirq*)arg;
117*344aa361SAndroid Build Coastguard Worker timer_cancel_sync(&u->tm);
118*344aa361SAndroid Build Coastguard Worker
119*344aa361SAndroid Build Coastguard Worker if (ttl_count) {
120*344aa361SAndroid Build Coastguard Worker LTRACEF("cnt=%u: %lld %lld\n", ttl_count, ttl_elapsed1, ttl_elapsed2);
121*344aa361SAndroid Build Coastguard Worker }
122*344aa361SAndroid Build Coastguard Worker }
123*344aa361SAndroid Build Coastguard Worker
124*344aa361SAndroid Build Coastguard Worker static const struct event_source_ops _tm_evt_ops = {
125*344aa361SAndroid Build Coastguard Worker .open = tm_uirq_open,
126*344aa361SAndroid Build Coastguard Worker .mask = tm_uirq_mask,
127*344aa361SAndroid Build Coastguard Worker .unmask = tm_uirq_unmask,
128*344aa361SAndroid Build Coastguard Worker .close = tm_uirq_close,
129*344aa361SAndroid Build Coastguard Worker };
130*344aa361SAndroid Build Coastguard Worker
uirq_test_init(uint level)131*344aa361SAndroid Build Coastguard Worker static void uirq_test_init(uint level) {
132*344aa361SAndroid Build Coastguard Worker int rc;
133*344aa361SAndroid Build Coastguard Worker
134*344aa361SAndroid Build Coastguard Worker /* register uirq interrupts */
135*344aa361SAndroid Build Coastguard Worker for (uint i = 0; i < countof(_tm_uirqs); i++) {
136*344aa361SAndroid Build Coastguard Worker struct timer_uirq* u = &_tm_uirqs[i];
137*344aa361SAndroid Build Coastguard Worker rc = uirq_register_sw_irq(&u->uirq, &_tm_evt_ops, u, &u->handle);
138*344aa361SAndroid Build Coastguard Worker if (rc < 0) {
139*344aa361SAndroid Build Coastguard Worker TRACEF("Failed (%d) to initialize test uirq %s\n", rc,
140*344aa361SAndroid Build Coastguard Worker u->uirq.name);
141*344aa361SAndroid Build Coastguard Worker }
142*344aa361SAndroid Build Coastguard Worker }
143*344aa361SAndroid Build Coastguard Worker }
144*344aa361SAndroid Build Coastguard Worker
145*344aa361SAndroid Build Coastguard Worker LK_INIT_HOOK(uirq_test, uirq_test_init, LK_INIT_LEVEL_APPS - 2);
146