blob: 4aa5f1dc7d2b680e0dca510b885bb8f44eeee056 [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
6#include "status.h"
7#include "table.h"
8#include "utils_def.h"
9#include "tb_common.h"
10#include "host_defs.h"
11#include "host_utils.h"
12#include "string.h"
13#include "granule.h"
14#include "tb_granules.h"
15#include "measurement.h"
16
17/* Declare a nondet function for registers information. */
18struct tb_regs nondet_tb_regs(void);
19
20struct tb_regs __tb_arb_regs(void)
21{
22 return nondet_tb_regs();
23}
24
25bool ResultEqual_2(unsigned int code, unsigned int expected)
26{
27 return code == expected;
28}
29
30/* TODO */
31bool ResultEqual_3(unsigned int code, unsigned int expected, unsigned int level)
32{
33 return true;
34}
35
36uint64_t Zeros(void)
37{
38 return UINT64_C(0);
39}
40
41bool __tb_arb_bool(void)
42{
43 return nondet_bool();
44}
45
46void __tb_lock_invariant(struct tb_lock_status *lock_status)
47{
48 /* TODO */
49}
50
51struct tb_lock_status __tb_lock_status(void)
52{
53 struct tb_lock_status r = {NULL};
54 return r;
55}
56
57extern struct granule granules[RMM_MAX_GRANULES];
58bool used_granules_buffer[HOST_NR_GRANULES] = { 0 };
59
60bool valid_pa(uint64_t addr)
61{
62 /*
63 * NOTE: the explicit pointer to integer type cast is necessary, as CBMC
64 * check fails without it.
65 */
66 if (GRANULE_ALIGNED(addr) && (uint64_t)granules_buffer <= addr &&
67 addr < (uint64_t)granules_buffer + sizeof(granules_buffer)) {
68 /*
69 * Keep these assserts for sanitary check, there was situation
70 * these asserts fail possibly due to CBMC dislike type
71 * conversion between number and pointer
72 */
73 ASSERT(GRANULE_ALIGNED(addr), "internal: `_valid_pa`, addr in alignment");
74 ASSERT(addr >= (uint64_t)granules_buffer,
75 "internal: `_valid_pa`, addr in lower range");
76 ASSERT(addr < (uint64_t)granules_buffer + sizeof(granules_buffer),
77 "internal: `_valid_pa`, addr in upper range");
78 return true;
79 }
80 return false;
81}
82
83struct granule *pa_to_granule_metadata_ptr(uint64_t addr)
84{
85 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
86
87 __ASSERT(idx >= 0, "internal: `_pa_to_granule_metadata_ptr`, addr is in lower range");
88 __ASSERT(idx < RMM_MAX_GRANULES,
89 "internal: `_pa_to_granule_metadata_ptr`, addr is in upper range");
90
91 return &granules[idx];
92}
93
94uint64_t granule_metadata_ptr_to_pa(struct granule *g_ptr)
95{
96 return (uint64_t)granules_buffer + (g_ptr - granules) * GRANULE_SIZE;
97}
98
99void *pa_to_granule_buffer_ptr(uint64_t addr)
100{
101 __ASSERT((unsigned char *)addr - granules_buffer >= 0,
102 "internal: `_pa_to_granule_buffer_ptr`, addr is in lower range");
103 /*
104 * NOTE: Has to do this strange computation and type cast so CBMC can
105 * handle.
106 */
107 return (void *)granules_buffer + ((unsigned char *)addr - granules_buffer);
108}
109
110void *granule_metadata_ptr_to_buffer_ptr(struct granule *g_ptr)
111{
112 if (!valid_granule_metadata_ptr(g_ptr)) {
113 return NULL;
114 }
115 return granules_buffer + (g_ptr - granules) * GRANULE_SIZE;
116}
117
118size_t granule_metadata_ptr_to_index(struct granule *g_ptr)
119{
120 return g_ptr - granules;
121}
122
123bool valid_granule_metadata_ptr(struct granule *p)
124{
125 return p >= granules
126 && p < granules + RMM_MAX_GRANULES;
127}
128
129/*
130 * Return the first index of `number` of unused continuous indice to both
131 * `granules` and `granules_buffer` arrays.
132 */
133size_t next_index(void)
134{
135 size_t index = nondet_size_t();
136
137 __ASSUME(unused_index(index));
138 if (!unused_index(index)) {
139 return -1;
140 }
141
142 REACHABLE;
143
144 return index;
145}
146
147bool unused_index(size_t index)
148{
149 if (index < HOST_NR_GRANULES && !used_granules_buffer[index]) {
150 return true;
151 }
152 return false;
153}
154
155void init_pa_page(const void *content, size_t size)
156{
157 unsigned long index = next_index();
158 unsigned long offset = index * GRANULE_SIZE;
159
160 (void)memcpy(granules_buffer + offset, content, size);
161 used_granules_buffer[index] = true;
162}
163
164struct granule *inject_granule_at(const struct granule *granule_metadata,
165 const void *src_page,
166 size_t src_size,
167 size_t index)
168{
169 size_t offset = index * GRANULE_SIZE;
170
171 granules[index] = *granule_metadata;
172 (void)memcpy(granules_buffer + offset, src_page, src_size);
173 used_granules_buffer[index] = true;
174 return &granules[index];
175}
176
177struct granule *inject_granule(const struct granule *granule_metadata,
178 const void *src_page,
179 size_t src_size)
180{
181 size_t index = next_index();
182
183 return inject_granule_at(granule_metadata, src_page, src_size, index);
184}
185