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
20enum vm_fault_type {
21    X86DataFault = seL4_DataFault,
22    X86InstructionFault = seL4_InstructionFault
23};
24
25typedef word_t vm_fault_type_t;
26
27enum vm_page_size {
28    X86_SmallPage,
29    X86_LargePage,
30    X64_HugePage
31};
32typedef word_t vm_page_size_t;
33
34enum frameSizeConstants {
35    X64SmallPageBits = seL4_PageBits,
36    X64LargePageBits = seL4_LargePageBits,
37    X64HugePageBits  = seL4_HugePageBits
38};
39
40enum 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};
50typedef word_t vm_page_map_type_t;
51
52/* Any changes to this function need to be replicated in pageBitsForSize_phys.
53 */
54static 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 */
75PHYS_CODE
76static 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 */
94uint32_t CONST getCacheLineSize(void);
95uint32_t CONST getCacheLineSizeBits(void);
96
97/* Flushes a specific memory range from the CPU cache */
98static inline void flushCacheLine(volatile void *vaddr)
99{
100    asm volatile("clflush %[vaddr]" : [vaddr] "+m"(*((volatile char *)vaddr)));
101}
102
103void flushCacheRange(void *vaddr, uint32_t size_bits);
104
105/* Disables a variety of prefetchers */
106bool_t disablePrefetchers(void);
107
108/* Enable user level access to the performance counters */
109BOOT_CODE void enablePMCUser(void);
110
111/* Flushes entire CPU Cache */
112static inline void x86_wbinvd(void)
113{
114    asm volatile("wbinvd" ::: "memory");
115}
116
117static 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 */
123bool_t init_ibrs(void);
124