1 /*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
8 #pragma once
9
10 #include <util.h>
11
12 #include <mode/hardware.h>
13
14 /* Privileged CSR definitions */
15 #define SSTATUS_SPIE 0x00000020
16 #define SSTATUS_SPP 0x00000100
17 #define SSTATUS_FS 0x00006000
18
19 #define SSTATUS_FS_CLEAN 0x00004000
20 #define SSTATUS_FS_INITIAL 0x00002000
21 #define SSTATUS_FS_DIRTY 0x00006000
22
23 #define SATP_MODE_OFF 0
24 #define SATP_MODE_SV32 1
25 #define SATP_MODE_SV39 8
26 #define SATP_MODE_SV48 9
27
28 #ifndef __ASSEMBLER__
29
30 #include <config.h>
31 #include <linker.h>
32
33 #include <arch/types.h>
34 #include <sel4/sel4_arch/constants.h>
35
36 /* The size is for HiFive Unleashed */
37 #define L1_CACHE_LINE_SIZE_BITS 6
38 #define L1_CACHE_LINE_SIZE BIT(L1_CACHE_LINE_SIZE_BITS)
39
40 #define PAGE_BITS seL4_PageBits
41
42 /* MMU RISC-V related definitions. See RISC-V manual priv-1.10 */
43
44 /* Extract the n-level PT index from a virtual address. This works for any
45 * configured RISC-V system with CONFIG_PT_LEVEL (which can be 2 on Sv32,
46 * 3 on Sv39, or 4 on Sv48)
47 */
48 #define RISCV_GET_PT_INDEX(addr, n) (((addr) >> (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)) & MASK(PT_INDEX_BITS))
49 #define RISCV_GET_LVL_PGSIZE_BITS(n) (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)
50 #define RISCV_GET_LVL_PGSIZE(n) BIT(RISCV_GET_LVL_PGSIZE_BITS((n)))
51 /*
52 * These values are defined in RISC-V priv-1.10 manual, they represent the
53 * exception codes saved in scause register (by the hardware) on traps.
54 */
55 enum vm_fault_type {
56 RISCVInstructionMisaligned = 0,
57 RISCVInstructionAccessFault = 1,
58 RISCVInstructionIllegal = 2,
59 RISCVBreakpoint = 3,
60 /* reserved */
61 RISCVLoadAccessFault = 5,
62 RISCVAddressMisaligned = 6,
63 RISCVStoreAccessFault = 7,
64 RISCVEnvCall = 8,
65 /* 9-11 reserved */
66 RISCVInstructionPageFault = 12,
67 RISCVLoadPageFault = 13,
68 /* 14 - reserved */
69 RISCVStorePageFault = 15
70 /* >= 16 reserved */
71 };
72 typedef word_t vm_fault_type_t;
73
74 enum frameSizeConstants {
75 RISCVPageBits = seL4_PageBits,
76 RISCVMegaPageBits = seL4_LargePageBits,
77 #if CONFIG_PT_LEVELS > 2
78 RISCVGigaPageBits = seL4_HugePageBits,
79 #endif
80 #if CONFIG_PT_LEVELS > 3
81 RISCVTeraPageBits = seL4_TeraPageBits
82 #endif
83 };
84
85 enum vm_page_size {
86 RISCV_4K_Page,
87 RISCV_Mega_Page,
88 RISCV_Giga_Page,
89 RISCV_Tera_Page
90 };
91 typedef word_t vm_page_size_t;
92
pageBitsForSize(vm_page_size_t pagesize)93 static inline word_t CONST pageBitsForSize(vm_page_size_t pagesize)
94 {
95 switch (pagesize) {
96 case RISCV_4K_Page:
97 return RISCVPageBits;
98
99 case RISCV_Mega_Page:
100 return RISCVMegaPageBits;
101
102 #if CONFIG_PT_LEVELS > 2
103 case RISCV_Giga_Page:
104 return RISCVGigaPageBits;
105 #endif
106
107 #if CONFIG_PT_LEVELS > 3
108 case RISCV_Tera_Page:
109 return RISCVTeraPageBits;
110 #endif
111
112 default:
113 fail("Invalid page size");
114 }
115 }
116
arch_clean_invalidate_caches(void)117 static inline void arch_clean_invalidate_caches(void)
118 {
119 /* RISC-V doesn't have an architecture defined way of flushing caches */
120 }
121 #endif /* __ASSEMBLER__ */
122
123 #define LOAD_S STRINGIFY(LOAD)
124 #define STORE_S STRINGIFY(STORE)
125
126 #define IPI_MEM_BARRIER \
127 do { \
128 asm volatile("fence rw,rw" ::: "memory"); \
129 } while (0)
130
131