coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
vm.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-4-Clause-UC */
2 
3 #ifndef _VM_H
4 #define _VM_H
5 
6 #include <string.h>
7 #include <stdint.h>
8 #include <arch/encoding.h>
9 
10 #define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
11 #define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
12 
13 void mstatus_init(void); // need to setup mstatus so we know we have virtual memory
14 
15 #define DEFINE_MPRV_READ_FLAGS(name, type, insn, flags) \
16  static inline type name(type *p); \
17  static inline type name(type *p) \
18  { \
19  size_t mprv = flags; \
20  type value; \
21  asm ( \
22  "csrs mstatus, %1\n" \
23  STRINGIFY(insn) " %0, 0(%2)\n" \
24  "csrc mstatus, %1\n" \
25  : "=&r"(value) : "r"(mprv), "r"(p) : "memory" \
26  ); \
27  return value; \
28  }
29 
30 #define DEFINE_MPRV_READ(name, type, insn) \
31  DEFINE_MPRV_READ_FLAGS(name, type, insn, MSTATUS_MPRV)
32 
33 #define DEFINE_MPRV_READ_MXR(name, type, insn) \
34  DEFINE_MPRV_READ_FLAGS(name, type, insn, MSTATUS_MPRV | MSTATUS_MXR)
35 
36 #define DEFINE_MPRV_WRITE(name, type, insn) \
37  static inline void name(type *p, type value); \
38  static inline void name(type *p, type value) \
39  { \
40  size_t mprv = MSTATUS_MPRV; \
41  asm ( \
42  "csrs mstatus, %0\n" \
43  STRINGIFY(insn) " %1, 0(%2)\n" \
44  "csrc mstatus, %0\n" \
45  :: "r"(mprv), "r"(value), "r"(p) : "memory" \
46  ); \
47  }
48 
49 /*
50  * mprv_{read,write}_* - Modified privilege memory access functions.
51  *
52  * These inline functions perform a read or write memory operation with the
53  * mstatus.MPRV bit set. This causes the memory protections and translation of
54  * the previous mode (e.g. U-mode, if we're handling a trap from U-mode) to be
55  * applied.
56  *
57  * The user of these functions must make sure to avoid trap loops through
58  * unaligned memory accesses.
59  */
60 DEFINE_MPRV_READ(mprv_read_u8, uint8_t, lbu)
61 DEFINE_MPRV_READ(mprv_read_u16, uint16_t, lhu)
62 DEFINE_MPRV_READ(mprv_read_u32, uint32_t, lwu)
63 DEFINE_MPRV_READ(mprv_read_u64, uint64_t, ld)
64 DEFINE_MPRV_READ(mprv_read_long, long, ld)
65 DEFINE_MPRV_READ(mprv_read_ulong, unsigned long, ld)
66 DEFINE_MPRV_READ_MXR(mprv_read_mxr_u8, uint8_t, lbu)
67 DEFINE_MPRV_READ_MXR(mprv_read_mxr_u16, uint16_t, lhu)
68 DEFINE_MPRV_READ_MXR(mprv_read_mxr_u32, uint32_t, lwu)
69 DEFINE_MPRV_READ_MXR(mprv_read_mxr_u64, uint64_t, ld)
70 DEFINE_MPRV_READ_MXR(mprv_read_mxr_long, long, ld)
71 DEFINE_MPRV_READ_MXR(mprv_read_mxr_ulong, unsigned long, ld)
72 DEFINE_MPRV_WRITE(mprv_write_u8, uint8_t, sb)
73 DEFINE_MPRV_WRITE(mprv_write_u16, uint16_t, sh)
74 DEFINE_MPRV_WRITE(mprv_write_u32, uint32_t, sw)
75 DEFINE_MPRV_WRITE(mprv_write_u64, uint64_t, sd)
76 DEFINE_MPRV_WRITE(mprv_write_long, long, sd)
77 DEFINE_MPRV_WRITE(mprv_write_ulong, unsigned long, sd)
78 
79 #if __riscv_xlen == 32
80  DEFINE_MPRV_READ(mprv_read_uintptr_t, uintptr_t, lw)
81  DEFINE_MPRV_READ(mprv_write_uintptr_t, uintptr_t, sw)
82 #elif __riscv_xlen == 64
83  DEFINE_MPRV_READ(mprv_read_uintptr_t, uintptr_t, ld)
84  DEFINE_MPRV_READ(mprv_write_uintptr_t, uintptr_t, sd)
85 #endif
86 
87 #undef DEFINE_MPRV_READ_FLAGS
88 #undef DEFINE_MPRV_READ
89 #undef DEFINE_MPRV_READ_MXR
90 #undef DEFINE_MPRV_WRITE
91 
92 #endif
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
void mstatus_init(void)
#define DEFINE_MPRV_READ_MXR(name, type, insn)
Definition: vm.h:33
#define DEFINE_MPRV_READ(name, type, insn)
Definition: vm.h:30
#define DEFINE_MPRV_WRITE(name, type, insn)
Definition: vm.h:36