1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#pragma once
8
9#include <config.h>
10#include <types.h>
11#include <api/failures.h>
12#include <object/structures.h>
13#include <plat/machine.h>
14
15#define IT_ASID 1 /* initial thread's ASID */
16
17
18struct lookupPTSlot_ret {
19    exception_t status;
20    pte_t      *ptSlot;
21};
22typedef struct lookupPTSlot_ret lookupPTSlot_ret_t;
23
24struct lookupPDSlot_ret {
25    exception_t status;
26    pde_t      *pdSlot;
27};
28typedef struct lookupPDSlot_ret lookupPDSlot_ret_t;
29
30struct findVSpaceForASID_ret {
31    exception_t status;
32    vspace_root_t *vspace_root;
33};
34typedef struct findVSpaceForASID_ret findVSpaceForASID_ret_t;
35
36void init_boot_pd(void);
37void enable_paging(void);
38bool_t map_kernel_window(
39    uint32_t num_ioapic,
40    paddr_t   *ioapic_paddrs,
41    uint32_t   num_drhu,
42    paddr_t   *drhu_list
43);
44bool_t map_skim_window(vptr_t skim_start, vptr_t skim_end);
45bool_t map_kernel_window_devices(
46    pte_t *pt,
47    uint32_t num_ioapic,
48    paddr_t   *ioapic_paddrs,
49    uint32_t   num_drhu,
50    paddr_t   *drhu_list
51);
52
53void init_tss(tss_t *tss);
54void init_gdt(gdt_entry_t *gdt, tss_t *tss);
55void init_idt_entry(idt_entry_t *idt, interrupt_t interrupt, void(*handler)(void));
56vspace_root_t *getValidNativeRoot(cap_t vspace_cap);
57pde_t *get_boot_pd(void);
58void *map_temp_boot_page(void *entry, uint32_t large_pages);
59bool_t init_vm_state(void);
60void init_dtrs(void);
61void map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap);
62void map_it_pd_cap(cap_t vspace_cap, cap_t pd_cap);
63void map_it_frame_cap(cap_t vspace_cap, cap_t frame_cap);
64void write_it_asid_pool(cap_t it_ap_cap, cap_t it_vspace_cap);
65bool_t init_pat_msr(void);
66cap_t create_it_address_space(cap_t root_cnode_cap, v_region_t it_v_reg);
67
68/* ==================== BOOT CODE FINISHES HERE ==================== */
69
70void idle_thread(void);
71#define idleThreadStart (&idle_thread)
72
73bool_t isVTableRoot(cap_t cap);
74
75asid_map_t findMapForASID(asid_t asid);
76
77lookupPTSlot_ret_t lookupPTSlot(vspace_root_t *vspace, vptr_t vptr);
78lookupPDSlot_ret_t lookupPDSlot(vspace_root_t *vspace, vptr_t vptr);
79void copyGlobalMappings(vspace_root_t *new_vspace);
80word_t *PURE lookupIPCBuffer(bool_t isReceiver, tcb_t *thread);
81exception_t handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType);
82void unmapPageDirectory(asid_t asid, vptr_t vaddr, pde_t *pd);
83void unmapPageTable(asid_t, vptr_t vaddr, pte_t *pt);
84
85exception_t performASIDPoolInvocation(asid_t asid, asid_pool_t *poolPtr, cte_t *vspaceCapSlot);
86exception_t performASIDControlInvocation(void *frame, cte_t *slot, cte_t *parent, asid_t asid_base);
87void hwASIDInvalidate(asid_t asid, vspace_root_t *vspace);
88void deleteASIDPool(asid_t asid_base, asid_pool_t *pool);
89void deleteASID(asid_t asid, vspace_root_t *vspace);
90findVSpaceForASID_ret_t findVSpaceForASID(asid_t asid);
91
92void unmapPage(vm_page_size_t page_size, asid_t asid, vptr_t vptr, void *pptr);
93/* returns whether the translation was removed and needs to be flushed from the hardware (i.e. tlb) */
94bool_t modeUnmapPage(vm_page_size_t page_size, vspace_root_t *vroot, vptr_t vptr, void *pptr);
95exception_t decodeX86ModeMapPage(word_t invLabel, vm_page_size_t page_size, cte_t *cte, cap_t cap,
96                                 vspace_root_t *vroot, vptr_t vptr, paddr_t paddr, vm_rights_t vm_rights, vm_attributes_t vm_attr);
97void setVMRoot(tcb_t *tcb);
98bool_t CONST isValidVTableRoot(cap_t cap);
99bool_t CONST isValidNativeRoot(cap_t cap);
100exception_t checkValidIPCBuffer(vptr_t vptr, cap_t cap);
101vm_rights_t CONST maskVMRights(vm_rights_t vm_rights, seL4_CapRights_t cap_rights_mask);
102void flushTable(vspace_root_t *vspace, word_t vptr, pte_t *pt, asid_t asid);
103
104exception_t decodeX86MMUInvocation(word_t invLabel, word_t length, cptr_t cptr, cte_t *cte,
105                                   cap_t cap, extra_caps_t excaps, word_t *buffer);
106
107exception_t decodeX86ModeMMUInvocation(word_t invLabel, word_t length, cptr_t cptr, cte_t *cte,
108                                       cap_t cap, extra_caps_t excaps, word_t *buffer);
109
110exception_t decodeIA32PageDirectoryInvocation(word_t invLabel, word_t length, cte_t *cte, cap_t cap,
111                                              extra_caps_t excaps, word_t *buffer);
112
113/* common functions for x86 */
114exception_t decodeX86FrameInvocation(word_t invLabel, word_t length, cte_t *cte, cap_t cap, extra_caps_t excaps,
115                                     word_t *buffer);
116
117uint32_t CONST WritableFromVMRights(vm_rights_t vm_rights);
118uint32_t CONST SuperUserFromVMRights(vm_rights_t vm_rights);
119
120/* the following functions have the same names, but different
121 * implementations for 32-bit and 64-bit.
122 */
123
124pte_t CONST makeUserPTE(paddr_t paddr, vm_attributes_t vm_attr, vm_rights_t vm_rights);
125pte_t CONST makeUserPTEInvalid(void);
126pde_t CONST makeUserPDELargePage(paddr_t paddr, vm_attributes_t vm_attr, vm_rights_t vm_rights);
127pde_t CONST makeUserPDEPageTable(paddr_t paddr, vm_attributes_t vm_attr);
128pde_t CONST makeUserPDEInvalid(void);
129
130
131#ifdef CONFIG_PRINTING
132void Arch_userStackTrace(tcb_t *tptr);
133#endif
134
135static inline bool_t checkVPAlignment(vm_page_size_t sz, word_t w)
136{
137    return IS_ALIGNED(w, pageBitsForSize(sz));
138}
139
140