blob: 629c43d536faee234138fc375ddccd9cd312e442 [file] [log] [blame]
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +02001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
Mate Toth-Pala18676e2023-10-27 17:05:01 +02006#include "granule.h"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +02007#include "host_defs.h"
8#include "host_utils.h"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +02009#include "measurement.h"
Mate Toth-Pala18676e2023-10-27 17:05:01 +020010#include "status.h"
11#include "string.h"
12#include "table.h"
13#include "tb_common.h"
14#include "tb_granules.h"
15#include "utils_def.h"
16
Soby Mathewbdd30ee2023-11-28 09:50:28 +000017/* This array holds information on the injected granule's status in the GPT. */
18static enum granule_gpt granule_gpt_array[RMM_MAX_GRANULES];
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020019
20/* Declare a nondet function for registers information. */
21struct tb_regs nondet_tb_regs(void);
22
23struct tb_regs __tb_arb_regs(void)
24{
25 return nondet_tb_regs();
26}
27
28bool ResultEqual_2(unsigned int code, unsigned int expected)
29{
30 return code == expected;
31}
32
33/* TODO */
34bool ResultEqual_3(unsigned int code, unsigned int expected, unsigned int level)
35{
36 return true;
37}
38
39uint64_t Zeros(void)
40{
41 return UINT64_C(0);
42}
43
44bool __tb_arb_bool(void)
45{
46 return nondet_bool();
47}
48
49void __tb_lock_invariant(struct tb_lock_status *lock_status)
50{
51 /* TODO */
52}
53
54struct tb_lock_status __tb_lock_status(void)
55{
Mate Toth-Pala18676e2023-10-27 17:05:01 +020056 struct tb_lock_status r = {0UL};
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020057 return r;
58}
59
60extern struct granule granules[RMM_MAX_GRANULES];
61bool used_granules_buffer[HOST_NR_GRANULES] = { 0 };
62
63bool valid_pa(uint64_t addr)
64{
65 /*
66 * NOTE: the explicit pointer to integer type cast is necessary, as CBMC
67 * check fails without it.
68 */
69 if (GRANULE_ALIGNED(addr) && (uint64_t)granules_buffer <= addr &&
70 addr < (uint64_t)granules_buffer + sizeof(granules_buffer)) {
71 /*
72 * Keep these assserts for sanitary check, there was situation
73 * these asserts fail possibly due to CBMC dislike type
74 * conversion between number and pointer
75 */
76 ASSERT(GRANULE_ALIGNED(addr), "internal: `_valid_pa`, addr in alignment");
77 ASSERT(addr >= (uint64_t)granules_buffer,
78 "internal: `_valid_pa`, addr in lower range");
79 ASSERT(addr < (uint64_t)granules_buffer + sizeof(granules_buffer),
80 "internal: `_valid_pa`, addr in upper range");
81 return true;
82 }
83 return false;
84}
85
86struct granule *pa_to_granule_metadata_ptr(uint64_t addr)
87{
88 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
89
90 __ASSERT(idx >= 0, "internal: `_pa_to_granule_metadata_ptr`, addr is in lower range");
91 __ASSERT(idx < RMM_MAX_GRANULES,
92 "internal: `_pa_to_granule_metadata_ptr`, addr is in upper range");
93
94 return &granules[idx];
95}
96
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010097uint64_t granule_metadata_ptr_to_pa(struct granule *g_ptr)
98{
99 return (uint64_t)granules_buffer + (g_ptr - granules) * GRANULE_SIZE;
100}
101
102void *pa_to_granule_buffer_ptr(uint64_t addr)
103{
104 __ASSERT((unsigned char *)addr - granules_buffer >= 0,
105 "internal: `_pa_to_granule_buffer_ptr`, addr is in lower range");
106 /*
107 * CBMC has difficulty doing an integer->object mapping, when the
108 * integer is the address of the expected object, and the integer is not
109 * derived from a pointer.
110 * So instead of simply returning addr we need to tell CBMC that the
111 * object we are looking for is in the `granules_buffer` array, at an
112 * offset. To calculate the offset we can use `addr`, and the address of
113 * `granules_buffer`.
114 * For details see https://github.com/diffblue/cbmc/issues/8103
115 */
116 return (void *)granules_buffer + ((unsigned char *)addr - granules_buffer);
117}
118
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200119bool valid_granule_metadata_ptr(struct granule *p)
120{
121 return p >= granules
122 && p < granules + RMM_MAX_GRANULES;
123}
124
125/*
126 * Return the first index of `number` of unused continuous indice to both
127 * `granules` and `granules_buffer` arrays.
128 */
129size_t next_index(void)
130{
131 size_t index = nondet_size_t();
132
133 __ASSUME(unused_index(index));
134 if (!unused_index(index)) {
135 return -1;
136 }
137
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200138 return index;
139}
140
141bool unused_index(size_t index)
142{
143 if (index < HOST_NR_GRANULES && !used_granules_buffer[index]) {
144 return true;
145 }
146 return false;
147}
148
149void init_pa_page(const void *content, size_t size)
150{
151 unsigned long index = next_index();
152 unsigned long offset = index * GRANULE_SIZE;
153
154 (void)memcpy(granules_buffer + offset, content, size);
155 used_granules_buffer[index] = true;
156}
157
158struct granule *inject_granule_at(const struct granule *granule_metadata,
159 const void *src_page,
160 size_t src_size,
161 size_t index)
162{
163 size_t offset = index * GRANULE_SIZE;
164
Mate Toth-Palc751c0d2023-11-14 16:56:41 +0100165 if (granule_metadata->state == GRANULE_STATE_NS) {
166 /* initialise the granules as either secure or non-secure */
167 granule_gpt_array[index] = nondet_bool() ? GPT_SECURE : GPT_NS;
168 } else {
169 granule_gpt_array[index] = GPT_REALM;
170 }
171
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200172 granules[index] = *granule_metadata;
173 (void)memcpy(granules_buffer + offset, src_page, src_size);
174 used_granules_buffer[index] = true;
175 return &granules[index];
176}
177
178struct granule *inject_granule(const struct granule *granule_metadata,
179 const void *src_page,
180 size_t src_size)
181{
182 size_t index = next_index();
183
184 return inject_granule_at(granule_metadata, src_page, src_size, index);
185}
186
Soby Mathewbdd30ee2023-11-28 09:50:28 +0000187enum granule_gpt get_granule_gpt(uint64_t addr)
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200188{
189 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
190
Soby Mathewbdd30ee2023-11-28 09:50:28 +0000191 return granule_gpt_array[idx];
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200192}
193
Soby Mathewbdd30ee2023-11-28 09:50:28 +0000194void set_granule_gpt(uint64_t addr, enum granule_gpt granule_gpt)
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200195{
196 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
197
Soby Mathewbdd30ee2023-11-28 09:50:28 +0000198 granule_gpt_array[idx] = granule_gpt;
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200199}