1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * This software may be distributed and modified according to the terms of
5 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
6 * See "LICENSE_GPLv2.txt" for details.
7 *
8 * @TAG(GD_GPL)
9 */
10
11#ifndef __ARCH_OBJECT_STRUCTURES_H
12#define __ARCH_OBJECT_STRUCTURES_H
13
14#include <assert.h>
15#include <config.h>
16#include <util.h>
17#include <api/types.h>
18#include <api/macros.h>
19#include <arch/types.h>
20#include <arch/object/structures_gen.h>
21#include <arch/machine/hardware.h>
22#include <arch/machine/registerset.h>
23#include <arch/api/constants.h>
24
25enum tcb_arch_cnode_index {
26#ifdef CONFIG_VTX
27    /* VSpace root for running any associated VCPU in */
28    tcbArchEPTRoot = tcbCNodeEntries,
29    tcbArchCNodeEntries
30#else
31    tcbArchCNodeEntries = tcbCNodeEntries
32#endif
33};
34
35typedef struct arch_tcb {
36    user_context_t tcbContext;
37#ifdef CONFIG_VTX
38    /* Pointer to associated VCPU. NULL if not associated.
39     * tcb->tcbVCPU->vcpuTCB == tcb. */
40    struct vcpu *tcbVCPU;
41#endif /* CONFIG_VTX */
42} arch_tcb_t;
43
44struct user_data {
45    word_t words[BIT(seL4_PageBits) / sizeof(word_t)];
46};
47
48typedef struct user_data user_data_t;
49
50struct user_data_device {
51    word_t words[BIT(seL4_PageBits) / sizeof(word_t)];
52};
53
54typedef struct user_data_device user_data_device_t;
55
56#define SEL_NULL    GDT_NULL
57#define SEL_CS_0    (GDT_CS_0 << 3)
58#define SEL_DS_0    (GDT_DS_0 << 3)
59#define SEL_CS_3    ((GDT_CS_3 << 3) | 3)
60#define SEL_DS_3    ((GDT_DS_3 << 3) | 3)
61#define SEL_TSS     (GDT_TSS << 3)
62#define SEL_TLS     ((GDT_TLS << 3) | 3)
63#define SEL_IPCBUF  ((GDT_IPCBUF << 3) | 3)
64
65#define IDT_ENTRIES 256
66
67#define VTD_RT_SIZE_BITS  12
68
69#define VTD_CTE_SIZE_BITS 3
70#define VTD_CTE_PTR(r)    ((vtd_cte_t*)(r))
71#define VTD_CT_BITS       9
72#define VTD_CT_SIZE_BITS  (VTD_CT_BITS + VTD_CTE_SIZE_BITS)
73
74#define VTD_PTE_SIZE_BITS 3
75#define VTD_PTE_PTR(r)    ((vtd_pte_t*)(r))
76#define VTD_PT_INDEX_BITS       9
77
78compile_assert(vtd_pt_size_sane, VTD_PT_INDEX_BITS + VTD_PTE_SIZE_BITS == seL4_IOPageTableBits)
79
80#ifdef CONFIG_VTX
81
82#define EPT_PML4E_SIZE_BITS seL4_X86_EPTPML4EntryBits
83#define EPT_PML4_INDEX_BITS seL4_X86_EPTPML4IndexBits
84#define EPT_PDPTE_SIZE_BITS seL4_X86_EPTPDPTEntryBits
85#define EPT_PDPT_INDEX_BITS seL4_X86_EPTPDPTIndexBits
86#define EPT_PDE_SIZE_BITS   seL4_X86_EPTPDEntryBits
87#define EPT_PD_INDEX_BITS   seL4_X86_EPTPDIndexBits
88#define EPT_PTE_SIZE_BITS   seL4_X86_EPTPTEntryBits
89#define EPT_PT_INDEX_BITS   seL4_X86_EPTPTIndexBits
90
91#define EPT_PT_INDEX_OFFSET (seL4_PageBits)
92#define EPT_PD_INDEX_OFFSET (EPT_PT_INDEX_OFFSET + EPT_PT_INDEX_BITS)
93#define EPT_PDPT_INDEX_OFFSET (EPT_PD_INDEX_OFFSET + EPT_PD_INDEX_BITS)
94#define EPT_PML4_INDEX_OFFSET (EPT_PDPT_INDEX_OFFSET + EPT_PDPT_INDEX_BITS)
95
96#define GET_EPT_PML4_INDEX(x) ( (((uint64_t)(x)) >> (EPT_PML4_INDEX_OFFSET)) & MASK(EPT_PML4_INDEX_BITS))
97#define GET_EPT_PDPT_INDEX(x) ( ((x) >> (EPT_PDPT_INDEX_OFFSET)) & MASK(EPT_PDPT_INDEX_BITS))
98#define GET_EPT_PD_INDEX(x) ( ((x) >> (EPT_PD_INDEX_OFFSET)) & MASK(EPT_PD_INDEX_BITS))
99#define GET_EPT_PT_INDEX(x) ( ((x) >> (EPT_PT_INDEX_OFFSET)) & MASK(EPT_PT_INDEX_BITS))
100
101#define EPT_PML4E_PTR(r)     ((ept_pml4e_t *)(r))
102#define EPT_PML4E_PTR_PTR(r) ((ept_pml4e_t **)(r))
103#define EPT_PML4E_REF(p)     ((word_t)(p))
104
105#define EPT_PML4_SIZE_BITS seL4_X86_EPTPML4Bits
106#define EPT_PML4_PTR(r)    ((ept_pml4e_t *)(r))
107#define EPT_PML4_REF(p)    ((word_t)(p))
108
109#define EPT_PDPTE_PTR(r)     ((ept_pdpte_t *)(r))
110#define EPT_PDPTE_PTR_PTR(r) ((ept_pdpte_t **)(r))
111#define EPT_PDPTE_REF(p)     ((word_t)(p))
112
113#define EPT_PDPT_SIZE_BITS seL4_X86_EPTPDPTBits
114#define EPT_PDPT_PTR(r)    ((ept_pdpte_t *)(r))
115#define EPT_PDPT_REF(p)    ((word_t)(p))
116
117#define EPT_PDE_PTR(r)     ((ept_pde_t *)(r))
118#define EPT_PDE_PTR_PTR(r) ((ept_pde_t **)(r))
119#define EPT_PDE_REF(p)     ((word_t)(p))
120
121#define EPT_PD_SIZE_BITS seL4_X86_EPTPDBits
122#define EPT_PD_PTR(r)    ((ept_pde_t *)(r))
123#define EPT_PD_REF(p)    ((word_t)(p))
124
125#define EPT_PTE_PTR(r)    ((ept_pte_t *)(r))
126#define EPT_PTE_REF(p)    ((word_t)(p))
127
128#define EPT_PT_SIZE_BITS seL4_X86_EPTPTBits
129#define EPT_PT_PTR(r)    ((ept_pte_t *)(r))
130#define EPT_PT_REF(p)    ((word_t)(p))
131
132#define VCPU_PTR(r)       ((vcpu_t *)(r))
133#define VCPU_REF(p)       ((word_t)(p))
134
135#endif /* CONFIG_VTX */
136
137struct rdmsr_safe_result {
138    uint64_t value;
139    bool_t success;
140};
141
142typedef struct rdmsr_safe_result rdmsr_safe_result_t;
143
144/* helper structure for filling descriptor registers */
145typedef struct gdt_idt_ptr {
146    uint16_t limit;
147    word_t base;
148} __attribute__((packed)) gdt_idt_ptr_t;
149
150enum vm_rights {
151    VMKernelOnly = 1,
152    VMReadOnly = 2,
153    VMReadWrite = 3
154};
155typedef word_t vm_rights_t;
156
157#include <mode/object/structures.h>
158
159static inline word_t CONST
160cap_get_archCapSizeBits(cap_t cap)
161{
162    cap_tag_t ctag;
163
164    ctag = cap_get_capType(cap);
165
166    switch (ctag) {
167    case cap_frame_cap:
168        return pageBitsForSize(cap_frame_cap_get_capFSize(cap));
169
170    case cap_page_table_cap:
171        return seL4_PageTableBits;
172
173    case cap_page_directory_cap:
174        return seL4_PageDirBits;
175
176    case cap_io_port_cap:
177        return 0;
178
179#ifdef CONFIG_IOMMU
180    case cap_io_space_cap:
181        return 0;
182    case cap_io_page_table_cap:
183        return seL4_IOPageTableBits;
184#endif
185
186    case cap_asid_control_cap:
187        return 0;
188
189    case cap_asid_pool_cap:
190        return seL4_ASIDPoolBits;
191
192#ifdef CONFIG_VTX
193    case cap_vcpu_cap:
194        return seL4_X86_VCPUBits;
195
196    case cap_ept_pml4_cap:
197        return seL4_X86_EPTPML4Bits;
198    case cap_ept_pdpt_cap:
199        return seL4_X86_EPTPDPTBits;
200    case cap_ept_pd_cap:
201        return seL4_X86_EPTPDBits;
202    case cap_ept_pt_cap:
203        return seL4_X86_EPTPTBits;
204#endif /* CONFIG_VTX */
205
206    default:
207        return cap_get_modeCapSizeBits(cap);
208    }
209}
210
211static inline bool_t CONST
212cap_get_archCapIsPhysical(cap_t cap)
213{
214    cap_tag_t ctag;
215
216    ctag = cap_get_capType(cap);
217
218    switch (ctag) {
219
220    case cap_frame_cap:
221        return true;
222
223    case cap_page_table_cap:
224        return true;
225
226    case cap_page_directory_cap:
227        return true;
228
229    case cap_io_port_cap:
230        return false;
231
232#ifdef CONFIG_IOMMU
233    case cap_io_space_cap:
234        return false;
235
236    case cap_io_page_table_cap:
237        return true;
238#endif
239
240    case cap_asid_control_cap:
241        return false;
242
243    case cap_asid_pool_cap:
244        return true;
245
246#ifdef CONFIG_VTX
247    case cap_ept_pt_cap:
248        return true;
249
250    case cap_ept_pd_cap:
251        return true;
252
253    case cap_ept_pdpt_cap:
254        return true;
255
256    case cap_ept_pml4_cap:
257        return true;
258#endif /* CONFIG_VTX */
259
260    default:
261        return cap_get_modeCapIsPhysical(cap);
262    }
263}
264
265static inline void * CONST
266cap_get_archCapPtr(cap_t cap)
267{
268    cap_tag_t ctag;
269
270    ctag = cap_get_capType(cap);
271
272    switch (ctag) {
273
274    case cap_frame_cap:
275        return (void *)(cap_frame_cap_get_capFBasePtr(cap));
276
277    case cap_page_table_cap:
278        return PD_PTR(cap_page_table_cap_get_capPTBasePtr(cap));
279
280    case cap_page_directory_cap:
281        return PT_PTR(cap_page_directory_cap_get_capPDBasePtr(cap));
282
283    case cap_io_port_cap:
284        return NULL;
285
286#ifdef CONFIG_IOMMU
287    case cap_io_space_cap:
288        return NULL;
289
290    case cap_io_page_table_cap:
291        return (void *)(cap_io_page_table_cap_get_capIOPTBasePtr(cap));
292#endif
293
294    case cap_asid_control_cap:
295        return NULL;
296
297    case cap_asid_pool_cap:
298        return ASID_POOL_PTR(cap_asid_pool_cap_get_capASIDPool(cap));
299
300#ifdef CONFIG_VTX
301    case cap_ept_pt_cap:
302        return EPT_PT_PTR(cap_ept_pt_cap_get_capPTBasePtr(cap));
303
304    case cap_ept_pd_cap:
305        return EPT_PD_PTR(cap_ept_pd_cap_get_capPDBasePtr(cap));
306
307    case cap_ept_pdpt_cap:
308        return EPT_PDPT_PTR(cap_ept_pdpt_cap_get_capPDPTBasePtr(cap));
309
310    case cap_ept_pml4_cap:
311        return EPT_PML4_PTR(cap_ept_pml4_cap_get_capPML4BasePtr(cap));
312#endif /* CONFIG_VTX */
313
314    default:
315        return cap_get_modeCapPtr(cap);
316    }
317}
318
319static inline bool_t CONST
320Arch_isCapRevocable(cap_t derivedCap, cap_t srcCap)
321{
322    switch (cap_get_capType(derivedCap)) {
323    case cap_io_port_cap:
324        return cap_get_capType(srcCap) == cap_io_port_control_cap;
325
326    default:
327        return false;
328    }
329}
330
331#endif /* __ARCH_OBJECT_STRUCTURES_H */
332