1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include <stdalign.h>
12 #include <stdint.h>
13 
14 #include "hf/ffa.h"
15 #include "hf/static_assert.h"
16 
17 #define PAGE_BITS 12
18 #define PAGE_LEVEL_BITS 9
19 #define STACK_ALIGN 16
20 #define FLOAT_REG_BYTES 16
21 #define NUM_GP_REGS 31
22 
23 /** The type of a page table entry (PTE). */
24 typedef uint64_t pte_t;
25 
26 /** Integer type large enough to hold a physical address. */
27 typedef uintptr_t uintpaddr_t;
28 
29 /** Integer type large enough to hold a virtual address. */
30 typedef uintptr_t uintvaddr_t;
31 
32 /** The integer type corresponding to the native register size. */
33 typedef uint64_t uintreg_t;
34 
35 /** The ID of a physical or virtual CPU. */
36 typedef uint64_t cpu_id_t;
37 
38 /** A bitset for AArch64 CPU features. */
39 typedef uint64_t arch_features_t;
40 
41 /**
42  * The struct for storing a floating point register.
43  *
44  * 2 64-bit integers used to avoid need for FP support at this level.
45  */
46 struct float_reg {
47 	alignas(FLOAT_REG_BYTES) uint64_t low;
48 	uint64_t high;
49 };
50 
51 static_assert(sizeof(struct float_reg) == FLOAT_REG_BYTES,
52 	      "Ensure float register type is 128 bits.");
53 
54 /** Arch-specific information about a VM. */
55 struct arch_vm {
56 	/**
57 	 * The index of the last vCPU of this VM which ran on each pCPU. Each
58 	 * element of this array should only be read or written by code running
59 	 * on that CPU, which avoids contention and so no lock is needed to
60 	 * access this field.
61 	 */
62 	ffa_vcpu_index_t last_vcpu_on_cpu[MAX_CPUS];
63 	arch_features_t trapped_features;
64 
65 	/*
66 	 * Masks for feature registers trappable by HCR_EL2.TID3.
67 	 */
68 	struct {
69 		uintreg_t id_aa64mmfr1_el1;
70 		uintreg_t id_aa64pfr0_el1;
71 		uintreg_t id_aa64dfr0_el1;
72 		uintreg_t id_aa64isar1_el1;
73 	} tid3_masks;
74 };
75 
76 /** Type to represent the register state of a vCPU. */
77 struct arch_regs {
78 	/* General purpose registers. */
79 	uintreg_t r[NUM_GP_REGS];
80 	uintreg_t pc;
81 	uintreg_t spsr;
82 
83 	/* Hypervisor configuration while a vCPU runs. */
84 	struct {
85 		uintreg_t hcr_el2;
86 		uintreg_t ttbr0_el2;
87 		uintreg_t sctlr_el2;
88 	} hyp_state;
89 
90 	/*
91 	 * System registers.
92 	 * NOTE: Ordering is important. If adding to or reordering registers
93 	 * below, make sure to update src/arch/aarch64/hypervisor/exceptions.S.
94 	 * Registers affected by VHE are grouped together followed by other
95 	 * registers.
96 	 *
97 	 */
98 	struct {
99 		uintreg_t sctlr_el1; /* Start VHE affected registers */
100 		uintreg_t cpacr_el1;
101 		uintreg_t ttbr0_el1;
102 		uintreg_t ttbr1_el1;
103 		uintreg_t tcr_el1;
104 		uintreg_t esr_el1;
105 		uintreg_t afsr0_el1;
106 		uintreg_t afsr1_el1;
107 		uintreg_t far_el1;
108 		uintreg_t mair_el1;
109 		uintreg_t vbar_el1;
110 		uintreg_t contextidr_el1;
111 		uintreg_t amair_el1;
112 		uintreg_t cntkctl_el1;
113 		uintreg_t elr_el1;
114 		uintreg_t spsr_el1; /* End VHE affected registers */
115 
116 		uintreg_t vmpidr_el2;
117 		uintreg_t csselr_el1;
118 		uintreg_t actlr_el1;
119 		uintreg_t tpidr_el0;
120 		uintreg_t tpidrro_el0;
121 		uintreg_t tpidr_el1;
122 		uintreg_t sp_el0;
123 		uintreg_t sp_el1;
124 		uintreg_t vtcr_el2;
125 		uintreg_t vttbr_el2;
126 		uintreg_t vstcr_el2;
127 		uintreg_t vsttbr_el2;
128 		uintreg_t mdcr_el2;
129 		uintreg_t mdscr_el1;
130 		uintreg_t pmccfiltr_el0;
131 		uintreg_t pmcr_el0;
132 		uintreg_t pmcntenset_el0;
133 		uintreg_t pmintenset_el1;
134 		uintreg_t cnthctl_el2;
135 		uintreg_t par_el1;
136 	} lazy;
137 
138 	/* Floating point registers. */
139 	struct float_reg fp[32];
140 	uintreg_t fpsr;
141 	uintreg_t fpcr;
142 
143 #if GIC_VERSION == 3 || GIC_VERSION == 4
144 	struct {
145 		uintreg_t ich_hcr_el2;
146 		uintreg_t icc_sre_el2;
147 	} gic;
148 #endif
149 
150 	/*
151 	 * Peripheral registers, handled separately from other system registers.
152 	 */
153 	struct {
154 		uintreg_t cntv_cval_el0;
155 		uintreg_t cntv_ctl_el0;
156 	} peripherals;
157 
158 #if BRANCH_PROTECTION
159 	/* Pointer authentication keys */
160 	struct {
161 		uintreg_t apiakeylo_el1;
162 		uintreg_t apiakeyhi_el1;
163 		uintreg_t apibkeylo_el1;
164 		uintreg_t apibkeyhi_el1;
165 		uintreg_t apdakeylo_el1;
166 		uintreg_t apdakeyhi_el1;
167 		uintreg_t apdbkeylo_el1;
168 		uintreg_t apdbkeyhi_el1;
169 		uintreg_t apgakeylo_el1;
170 		uintreg_t apgakeyhi_el1;
171 	} pac;
172 #endif
173 
174 #if ENABLE_MTE
175 	/* MTE registers. */
176 	struct {
177 		uintreg_t tfsr_el1;
178 		uintreg_t gcr_el1;
179 		uintreg_t rgsr_el1;
180 		uintreg_t tfsre0_el1;
181 	} mte;
182 #endif
183 };
184 
185 /** Type of interrupts */
186 enum interrupt_type {
187 	INTERRUPT_TYPE_IRQ,
188 	INTERRUPT_TYPE_FIQ,
189 };
190