blob: 225966d380d68b77c009bdd2fed829207eec154d [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
17/*
18 * This array holds information on whether the granule that is injected in
19 * RMM's granule array is set to NS in the GPT, or not.
20 */
21static bool granule_gpt_ns_array[RMM_MAX_GRANULES];
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020022
23/* Declare a nondet function for registers information. */
24struct tb_regs nondet_tb_regs(void);
25
26struct tb_regs __tb_arb_regs(void)
27{
28 return nondet_tb_regs();
29}
30
31bool ResultEqual_2(unsigned int code, unsigned int expected)
32{
33 return code == expected;
34}
35
36/* TODO */
37bool ResultEqual_3(unsigned int code, unsigned int expected, unsigned int level)
38{
39 return true;
40}
41
42uint64_t Zeros(void)
43{
44 return UINT64_C(0);
45}
46
47bool __tb_arb_bool(void)
48{
49 return nondet_bool();
50}
51
52void __tb_lock_invariant(struct tb_lock_status *lock_status)
53{
54 /* TODO */
55}
56
57struct tb_lock_status __tb_lock_status(void)
58{
Mate Toth-Pala18676e2023-10-27 17:05:01 +020059 struct tb_lock_status r = {0UL};
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020060 return r;
61}
62
63extern struct granule granules[RMM_MAX_GRANULES];
64bool used_granules_buffer[HOST_NR_GRANULES] = { 0 };
65
66bool valid_pa(uint64_t addr)
67{
68 /*
69 * NOTE: the explicit pointer to integer type cast is necessary, as CBMC
70 * check fails without it.
71 */
72 if (GRANULE_ALIGNED(addr) && (uint64_t)granules_buffer <= addr &&
73 addr < (uint64_t)granules_buffer + sizeof(granules_buffer)) {
74 /*
75 * Keep these assserts for sanitary check, there was situation
76 * these asserts fail possibly due to CBMC dislike type
77 * conversion between number and pointer
78 */
79 ASSERT(GRANULE_ALIGNED(addr), "internal: `_valid_pa`, addr in alignment");
80 ASSERT(addr >= (uint64_t)granules_buffer,
81 "internal: `_valid_pa`, addr in lower range");
82 ASSERT(addr < (uint64_t)granules_buffer + sizeof(granules_buffer),
83 "internal: `_valid_pa`, addr in upper range");
84 return true;
85 }
86 return false;
87}
88
89struct granule *pa_to_granule_metadata_ptr(uint64_t addr)
90{
91 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
92
93 __ASSERT(idx >= 0, "internal: `_pa_to_granule_metadata_ptr`, addr is in lower range");
94 __ASSERT(idx < RMM_MAX_GRANULES,
95 "internal: `_pa_to_granule_metadata_ptr`, addr is in upper range");
96
97 return &granules[idx];
98}
99
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200100bool valid_granule_metadata_ptr(struct granule *p)
101{
102 return p >= granules
103 && p < granules + RMM_MAX_GRANULES;
104}
105
106/*
107 * Return the first index of `number` of unused continuous indice to both
108 * `granules` and `granules_buffer` arrays.
109 */
110size_t next_index(void)
111{
112 size_t index = nondet_size_t();
113
114 __ASSUME(unused_index(index));
115 if (!unused_index(index)) {
116 return -1;
117 }
118
119 REACHABLE;
120
121 return index;
122}
123
124bool unused_index(size_t index)
125{
126 if (index < HOST_NR_GRANULES && !used_granules_buffer[index]) {
127 return true;
128 }
129 return false;
130}
131
132void init_pa_page(const void *content, size_t size)
133{
134 unsigned long index = next_index();
135 unsigned long offset = index * GRANULE_SIZE;
136
137 (void)memcpy(granules_buffer + offset, content, size);
138 used_granules_buffer[index] = true;
139}
140
141struct granule *inject_granule_at(const struct granule *granule_metadata,
142 const void *src_page,
143 size_t src_size,
144 size_t index)
145{
146 size_t offset = index * GRANULE_SIZE;
147
148 granules[index] = *granule_metadata;
149 (void)memcpy(granules_buffer + offset, src_page, src_size);
150 used_granules_buffer[index] = true;
151 return &granules[index];
152}
153
154struct granule *inject_granule(const struct granule *granule_metadata,
155 const void *src_page,
156 size_t src_size)
157{
158 size_t index = next_index();
159
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200160 if (granule_metadata->state == GRANULE_STATE_NS) {
161 granule_gpt_ns_array[index] = nondet_bool();
162 } else{
163 granule_gpt_ns_array[index] = false;
164 }
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200165 return inject_granule_at(granule_metadata, src_page, src_size, index);
166}
167
Mate Toth-Pala18676e2023-10-27 17:05:01 +0200168bool is_granule_gpt_ns(uint64_t addr)
169{
170 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
171
172 return granule_gpt_ns_array[idx];
173}
174
175void set_granule_gpt_ns(uint64_t addr, bool gpt_ns)
176{
177 uint64_t idx = (addr - (uint64_t)granules_buffer)/GRANULE_SIZE;
178
179 granule_gpt_ns_array[idx] = gpt_ns;
180}