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 <basic_types.h>
10 #include <config.h>
11 #include <arch/types.h>
12 #include <linker.h>
13 #include <sel4/sel4_arch/constants.h>
14 
15 #define PAGE_BITS seL4_PageBits
16 #define LARGE_PAGE_BITS seL4_LargePageBits
17 #define L1_CACHE_LINE_SIZE_BITS CTZL(CONFIG_CACHE_LN_SZ)
18 #define L1_CACHE_LINE_SIZE CONFIG_CACHE_LN_SZ
19 
20 enum vm_fault_type {
21     X86DataFault = seL4_DataFault,
22     X86InstructionFault = seL4_InstructionFault
23 };
24 
25 typedef word_t vm_fault_type_t;
26 
27 enum vm_page_size {
28     X86_SmallPage,
29     X86_LargePage,
30     X64_HugePage
31 };
32 typedef word_t vm_page_size_t;
33 
34 enum frameSizeConstants {
35     X64SmallPageBits = seL4_PageBits,
36     X64LargePageBits = seL4_LargePageBits,
37     X64HugePageBits  = seL4_HugePageBits
38 };
39 
40 enum vm_page_map_type {
41     X86_MappingNone = 0,
42     X86_MappingVSpace,
43 #ifdef CONFIG_IOMMU
44     X86_MappingIOSpace,
45 #endif
46 #ifdef CONFIG_VTX
47     X86_MappingEPT
48 #endif
49 };
50 typedef word_t vm_page_map_type_t;
51 
52 /* Any changes to this function need to be replicated in pageBitsForSize_phys.
53  */
pageBitsForSize(vm_page_size_t pagesize)54 static inline word_t CONST pageBitsForSize(vm_page_size_t pagesize)
55 {
56     switch (pagesize) {
57     case X86_SmallPage:
58         return seL4_PageBits;
59 
60     case X86_LargePage:
61         return seL4_LargePageBits;
62 
63     case X64_HugePage:
64         return seL4_HugePageBits;
65 
66     default:
67         fail("Invalid page size");
68     }
69 }
70 
71 /* This function is a duplicate of pageBitsForSize, needed for calls that occur
72  * before the MMU is turned on. Note that any changes to this function need to
73  * be replicated in pageBitsForSize.
74  */
75 PHYS_CODE
pageBitsForSize_phys(vm_page_size_t pagesize)76 static inline word_t CONST pageBitsForSize_phys(vm_page_size_t pagesize)
77 {
78     switch (pagesize) {
79     case X86_SmallPage:
80         return seL4_PageBits;
81 
82     case X86_LargePage:
83         return seL4_LargePageBits;
84 
85     case X64_HugePage:
86         return seL4_HugePageBits;
87 
88     default:
89         fail("Invalid page size");
90     }
91 }
92 
93 /* Returns the size of CPU's cacheline */
94 uint32_t CONST getCacheLineSize(void);
95 uint32_t CONST getCacheLineSizeBits(void);
96 
97 /* Flushes a specific memory range from the CPU cache */
flushCacheLine(volatile void * vaddr)98 static inline void flushCacheLine(volatile void *vaddr)
99 {
100     asm volatile("clflush %[vaddr]" : [vaddr] "+m"(*((volatile char *)vaddr)));
101 }
102 
103 void flushCacheRange(void *vaddr, uint32_t size_bits);
104 
105 /* Disables a variety of prefetchers */
106 bool_t disablePrefetchers(void);
107 
108 /* Enable user level access to the performance counters */
109 BOOT_CODE void enablePMCUser(void);
110 
111 /* Flushes entire CPU Cache */
x86_wbinvd(void)112 static inline void x86_wbinvd(void)
113 {
114     asm volatile("wbinvd" ::: "memory");
115 }
116 
arch_clean_invalidate_caches(void)117 static inline void arch_clean_invalidate_caches(void)
118 {
119     x86_wbinvd();
120 }
121 
122 /* Initialize Indirect Branch Restricted Speculation into the mode specified by the build configuration */
123 bool_t init_ibrs(void);
124