1 // © 2022 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #include <assert.h>
6 
7 #define timer_t hyp_timer_t
8 #include <hyptypes.h>
9 #undef timer_t
10 
11 #define register_t std_register_t
12 #include <stdio.h>
13 #include <stdlib.h>
14 #undef register_t
15 
16 #include <compiler.h>
17 #include <gpt.h>
18 #include <log.h>
19 #include <object.h>
20 #include <panic.h>
21 #include <partition.h>
22 #include <trace.h>
23 #include <util.h>
24 
25 #include "event_handlers.h"
26 #include "string_util.h"
27 #include "trace_helpers.h"
28 
29 gpt_t		gpt;
30 partition_t	host_partition;
31 trace_control_t hyp_trace;
32 
33 void
assert_failed(const char * file,int line,const char * func,const char * err)34 assert_failed(const char *file, int line, const char *func, const char *err)
35 {
36 	printf("Assert failed in %s at %s:%d: %s\n", func, file, line, err);
37 	exit(-1);
38 }
39 
40 void
panic(const char * str)41 panic(const char *str)
42 {
43 	printf("Panic: %s\n", str);
44 	exit(-1);
45 }
46 
47 static void
trace_and_log_init(void)48 trace_and_log_init(void)
49 {
50 	register_t flags = 0U;
51 
52 	TRACE_SET_CLASS(flags, ERROR);
53 	TRACE_SET_CLASS(flags, DEBUG);
54 
55 	atomic_init(&hyp_trace.enabled_class_flags, flags);
56 }
57 
58 void
trigger_trace_log_event(trace_id_t id,trace_action_t action,const char * arg0,register_t arg1,register_t arg2,register_t arg3,register_t arg4,register_t arg5)59 trigger_trace_log_event(trace_id_t id, trace_action_t action, const char *arg0,
60 			register_t arg1, register_t arg2, register_t arg3,
61 			register_t arg4, register_t arg5)
62 {
63 	char log[1024];
64 	(void)snprint(log, util_array_size(log), arg0, arg1, arg2, arg3, arg4,
65 		      arg5);
66 	puts(log);
67 }
68 
69 partition_t *
object_get_partition_additional(partition_t * partition)70 object_get_partition_additional(partition_t *partition)
71 {
72 	assert(partition != NULL);
73 
74 	return partition;
75 }
76 
77 void
object_put_partition(partition_t * partition)78 object_put_partition(partition_t *partition)
79 {
80 	assert(partition != NULL);
81 }
82 
83 partition_t *
partition_get_root(void)84 partition_get_root(void)
85 {
86 	return &host_partition;
87 }
88 
89 void_ptr_result_t
partition_alloc(partition_t * partition,size_t bytes,size_t min_alignment)90 partition_alloc(partition_t *partition, size_t bytes, size_t min_alignment)
91 {
92 	assert(partition != NULL);
93 	assert(bytes > 0U);
94 
95 	void *mem = aligned_alloc(min_alignment, bytes);
96 
97 	return (mem != NULL) ? void_ptr_result_ok(mem)
98 			     : void_ptr_result_error(ERROR_NOMEM);
99 }
100 
101 error_t
partition_free(partition_t * partition,void * mem,size_t bytes)102 partition_free(partition_t *partition, void *mem, size_t bytes)
103 {
104 	assert(partition != NULL);
105 	assert(bytes > 0U);
106 
107 	free(mem);
108 
109 	return OK;
110 }
111 
112 void
preempt_disable(void)113 preempt_disable(void)
114 {
115 }
116 
117 void
preempt_enable(void)118 preempt_enable(void)
119 {
120 }
121 
122 void
rcu_read_start(void)123 rcu_read_start(void)
124 {
125 }
126 
127 void
rcu_read_finish(void)128 rcu_read_finish(void)
129 {
130 }
131 
132 void
rcu_enqueue(rcu_entry_t * rcu_entry,rcu_update_class_t rcu_update_class)133 rcu_enqueue(rcu_entry_t *rcu_entry, rcu_update_class_t rcu_update_class)
134 {
135 	assert(rcu_update_class == RCU_UPDATE_CLASS_GPT_FREE_LEVEL);
136 
137 	(void)gpt_handle_rcu_free_level(rcu_entry);
138 }
139 
140 cpu_index_t
cpulocal_check_index(cpu_index_t cpu)141 cpulocal_check_index(cpu_index_t cpu)
142 {
143 	return cpu;
144 }
145 
146 cpu_index_t
cpulocal_get_index_unsafe(void)147 cpulocal_get_index_unsafe(void)
148 {
149 	return 0U;
150 }
151 
152 void
trigger_gpt_value_add_offset_event(gpt_type_t type,gpt_value_t * value,size_t offset)153 trigger_gpt_value_add_offset_event(gpt_type_t type, gpt_value_t *value,
154 				   size_t offset)
155 {
156 	if ((type == GPT_TYPE_TEST_A) || (type == GPT_TYPE_TEST_B) ||
157 	    (type == GPT_TYPE_TEST_C)) {
158 		gpt_tests_add_offset(type, value, offset);
159 	} else {
160 		// Nothing to do
161 	}
162 }
163 
164 bool
trigger_gpt_values_equal_event(gpt_type_t type,gpt_value_t x,gpt_value_t y)165 trigger_gpt_values_equal_event(gpt_type_t type, gpt_value_t x, gpt_value_t y)
166 {
167 	bool ret;
168 
169 	if ((type == GPT_TYPE_TEST_A) || (type == GPT_TYPE_TEST_B) ||
170 	    (type == GPT_TYPE_TEST_C)) {
171 		ret = gpt_tests_values_equal(x, y);
172 	} else if (GPT_TYPE_EMPTY) {
173 		ret = gpt_handle_empty_values_equal();
174 	} else {
175 		ret = false;
176 	}
177 
178 	return ret;
179 }
180 
181 error_t
trigger_gpt_walk_callback_event(gpt_callback_t callback,gpt_entry_t entry,size_t base,size_t size,gpt_arg_t arg)182 trigger_gpt_walk_callback_event(gpt_callback_t callback, gpt_entry_t entry,
183 				size_t base, size_t size, gpt_arg_t arg)
184 {
185 	error_t ret;
186 
187 	if (callback == GPT_CALLBACK_RESERVED) {
188 		gpt_handle_reserved_callback();
189 	} else if (callback == GPT_CALLBACK_TEST) {
190 		ret = gpt_tests_callback(entry, base, size, arg);
191 	} else {
192 		ret = ERROR_ARGUMENT_INVALID;
193 	}
194 
195 	return ret;
196 }
197 
198 int
main(void)199 main(void)
200 {
201 	trace_and_log_init();
202 
203 	gpt_handle_tests_init();
204 
205 	gpt_handle_tests_start();
206 
207 	return 0;
208 }
209