blob: 5668c5a613b41534c6252889d491fa7ddd410ce7 [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 "tb_granules.h"
7#include "tb_common.h"
8#include "buffer.h"
9#include "granule.h"
10#include "granule_types.h"
11#include "sizes.h"
12#include "host_defs.h"
13#include "host_utils.h"
14#include "platform_api.h"
15#include "string.h"
16
17extern struct granule granules[RMM_MAX_GRANULES];
18
19/* Chooses an arbitrary granule state. */
20bool valid_granule_state(enum granule_state value)
21{
22 return value == GRANULE_STATE_NS
23 || value == GRANULE_STATE_DELEGATED
24 || value == GRANULE_STATE_RD
25 || value == GRANULE_STATE_REC
26 || value == GRANULE_STATE_REC_AUX
27 || value == GRANULE_STATE_DATA
28 || value == GRANULE_STATE_RTT;
29}
30
31/* Ref to `__granule_assert_unlocked_invariants` function in `granule.h`. */
32bool valid_granule(struct granule value)
33{
34 if (value.lock.val != 0) {
35 return false;
36 }
37
38 switch (value.state) {
39 case GRANULE_STATE_NS:
40 case GRANULE_STATE_DELEGATED:
41 case GRANULE_STATE_DATA:
42 case GRANULE_STATE_REC_AUX: return value.refcount == 0;
43 /*
44 * refcount is used to check if RD and associated granules can
45 * be freed because they're no longer referenced by any other
46 * object. Can be any non-negative number.
47 */
48 case GRANULE_STATE_REC: return value.refcount <= 1;
49 case GRANULE_STATE_RTT: return value.refcount >= 0 &&
50 value.refcount <= GRANULE_SIZE / sizeof(uint64_t);
51 case GRANULE_STATE_RD: return true;
52 default: return false;
53 }
54 return false;
55}
56
57struct granule init_granule(void)
58{
59 struct granule rst = nondet_struct_granule();
60
61 __CPROVER_assume(valid_granule(rst));
62 return rst;
63}
64
65void init_granule_and_page(void)
66{
67 struct granule g = init_granule();
68 /* just write one byte when call the `inject_granule` functions */
69 char ns_granule[1] = { 0 };
70
71 inject_granule(&g, ns_granule, sizeof(ns_granule));
72}
73
74/*
75 * Implementation of pedicates
76 */
77bool AddrIsGranuleAligned(uint64_t addr)
78{
79 return GRANULE_ALIGNED(addr);
80}
81
82bool PaIsDelegable(uint64_t addr)
83{
84 return valid_pa(addr);
85}
86
87struct SPEC_granule Granule(uint64_t addr)
88{
89 if (!valid_pa(addr)) {
90 return nondet_struct_SPEC_granule();
91 }
92
93 struct granule *result = pa_to_granule_metadata_ptr(addr);
94
95 struct SPEC_granule spec_granule;
96
97 spec_granule.state = result->state;
98
99 switch (result->state) {
100 case GRANULE_STATE_NS:
101 case GRANULE_STATE_RTT:
102 spec_granule.gpt = GPT_NS;
103 break;
104 case GRANULE_STATE_RD:
105 case GRANULE_STATE_DATA:
106 case GRANULE_STATE_REC:
107 case GRANULE_STATE_DELEGATED:
108 spec_granule.gpt = GPT_REALM;
109 break;
110 default:
111 spec_granule.gpt = GPT_AAP;
112 }
113
114 return spec_granule;
115}