3
3
* "LICENSE" for information on usage and redistribution of this file.
4
4
*/
5
5
6
- #if !RV32_HAS (SYSTEM )
7
- #error "Do not manage to build this file unless you enable system support."
8
- #endif
9
-
10
6
#include <assert.h>
11
7
12
- #include "devices/plic.h"
13
- #include "devices/uart.h"
14
- #include "devices/virtio.h"
15
- #include "riscv_private.h"
16
-
17
- #define R 1
18
- #define W 0
8
+ #include "system.h"
19
9
20
- #if RV32_HAS ( SYSTEM ) && !RV32_HAS (ELF_LOADER )
10
+ #if !RV32_HAS (ELF_LOADER )
21
11
void emu_update_uart_interrupts (riscv_t * rv )
22
12
{
23
13
vm_attr_t * attr = PRIV (rv );
@@ -29,7 +19,7 @@ void emu_update_uart_interrupts(riscv_t *rv)
29
19
plic_update_interrupts (attr -> plic );
30
20
}
31
21
32
- static void emu_update_vblk_interrupts (riscv_t * rv )
22
+ void emu_update_vblk_interrupts (riscv_t * rv )
33
23
{
34
24
vm_attr_t * attr = PRIV (rv );
35
25
if (attr -> vblk -> interrupt_status )
@@ -38,112 +28,6 @@ static void emu_update_vblk_interrupts(riscv_t *rv)
38
28
attr -> plic -> active &= ~IRQ_VBLK_BIT ;
39
29
plic_update_interrupts (attr -> plic );
40
30
}
41
- /*
42
- * Linux kernel might create signal frame when returning from trap
43
- * handling, which modifies the SEPC CSR. Thus, the fault instruction
44
- * cannot always redo. For example, invalid memory access causes SIGSEGV.
45
- */
46
- extern bool need_handle_signal ;
47
- #define CHECK_PENDING_SIGNAL (rv , signal_flag ) \
48
- do { \
49
- signal_flag = (rv->csr_sepc != rv->last_csr_sepc); \
50
- } while (0)
51
-
52
- #define MMIO_R 1
53
- #define MMIO_W 0
54
-
55
- enum SUPPORTED_MMIO {
56
- MMIO_PLIC ,
57
- MMIO_UART ,
58
- MMIO_VIRTIOBLK ,
59
- };
60
-
61
- /* clang-format off */
62
- #define MMIO_OP (io , rw ) \
63
- switch(io){ \
64
- case MMIO_PLIC: \
65
- IIF(rw)( /* read */ \
66
- mmio_read_val = plic_read (PRIV (rv )-> plic , addr & 0x3FFFFFF ); \
67
- plic_update_interrupts (PRIV (rv )-> plic ); \
68
- return mmio_read_val ; \
69
- , /* write */ \
70
- plic_write (PRIV (rv )-> plic , addr & 0x3FFFFFF , val ); \
71
- plic_update_interrupts (PRIV (rv )-> plic ); \
72
- return ; \
73
- ) \
74
- break ; \
75
- case MMIO_UART : \
76
- IIF (rw )( /* read */ \
77
- mmio_read_val = u8250_read (PRIV (rv )-> uart , addr & 0xFFFFF ); \
78
- emu_update_uart_interrupts (rv ); \
79
- return mmio_read_val ; \
80
- , /* write */ \
81
- u8250_write (PRIV (rv )-> uart , addr & 0xFFFFF , val ); \
82
- emu_update_uart_interrupts (rv ); \
83
- return ; \
84
- ) \
85
- break ; \
86
- case MMIO_VIRTIOBLK : \
87
- IIF (rw )( /* read */ \
88
- mmio_read_val = virtio_blk_read (PRIV (rv )-> vblk , addr & 0xFFFFF ); \
89
- emu_update_vblk_interrupts (rv ); \
90
- return mmio_read_val ; \
91
- , /* write */ \
92
- virtio_blk_write (PRIV (rv )-> vblk , addr & 0xFFFFF , val ); \
93
- emu_update_vblk_interrupts (rv ); \
94
- return ; \
95
- ) \
96
- break ; \
97
- default : \
98
- rv_log_error ("Unknown MMIO type %d" , io ); \
99
- break ; \
100
- }
101
- /* clang-format on */
102
-
103
- #define MMIO_READ () \
104
- do { \
105
- uint32_t mmio_read_val; \
106
- if ((addr >> 28) == 0xF) { /* MMIO at 0xF_______ */ \
107
- /* 256 regions of 1MiB */ \
108
- switch ((addr >> 20 ) & MASK (8 )) { \
109
- case 0x0 : \
110
- case 0x2 : /* PLIC (0 - 0x3F) */ \
111
- MMIO_OP (MMIO_PLIC , MMIO_R ); \
112
- break ; \
113
- case 0x40 : /* UART */ \
114
- MMIO_OP (MMIO_UART , MMIO_R ); \
115
- break ; \
116
- case 0x42 : /* Virtio-blk */ \
117
- MMIO_OP (MMIO_VIRTIOBLK , MMIO_R ); \
118
- break ; \
119
- default : \
120
- __UNREACHABLE ; \
121
- break ; \
122
- } \
123
- } \
124
- } while (0 )
125
-
126
- #define MMIO_WRITE () \
127
- do { \
128
- if ((addr >> 28) == 0xF) { /* MMIO at 0xF_______ */ \
129
- /* 256 regions of 1MiB */ \
130
- switch ((addr >> 20 ) & MASK (8 )) { \
131
- case 0x0 : \
132
- case 0x2 : /* PLIC (0 - 0x3F) */ \
133
- MMIO_OP (MMIO_PLIC , MMIO_W ); \
134
- break ; \
135
- case 0x40 : /* UART */ \
136
- MMIO_OP (MMIO_UART , MMIO_W ); \
137
- break ; \
138
- case 0x42 : /* Virtio-blk */ \
139
- MMIO_OP (MMIO_VIRTIOBLK , MMIO_W ); \
140
- break ; \
141
- default : \
142
- __UNREACHABLE ; \
143
- break ; \
144
- } \
145
- } \
146
- } while (0 )
147
31
#endif
148
32
149
33
static bool ppn_is_valid (riscv_t * rv , uint32_t ppn )
@@ -221,8 +105,8 @@ pte_t *mmu_walk(riscv_t *rv, const uint32_t vaddr, uint32_t *level)
221
105
#define MMU_FAULT_CHECK (op , rv , pte , vaddr , access_bits ) \
222
106
mmu_##op##_fault_check(rv, pte, vaddr, access_bits)
223
107
#define MMU_FAULT_CHECK_IMPL (op , pgfault ) \
224
- static bool mmu_##op##_fault_check(riscv_t *rv, pte_t *pte, \
225
- uint32_t vaddr, uint32_t access_bits) \
108
+ bool mmu_##op##_fault_check(riscv_t *rv, pte_t *pte, uint32_t vaddr, \
109
+ uint32_t access_bits) \
226
110
{ \
227
111
uint32_t scause; \
228
112
uint32_t stval = vaddr; \
@@ -285,16 +169,6 @@ MMU_FAULT_CHECK_IMPL(ifetch, pagefault_insn)
285
169
MMU_FAULT_CHECK_IMPL (read , pagefault_load )
286
170
MMU_FAULT_CHECK_IMPL (write , pagefault_store )
287
171
288
- uint32_t ppn ;
289
- uint32_t offset ;
290
- #define get_ppn_and_offset () \
291
- do { \
292
- assert(pte); \
293
- ppn = *pte >> (RV_PG_SHIFT - 2) << RV_PG_SHIFT; \
294
- offset = level == 1 ? vaddr & MASK((RV_PG_SHIFT + 10)) \
295
- : vaddr & MASK(RV_PG_SHIFT); \
296
- } while (0)
297
-
298
172
/* The IO handler that operates when the Memory Management Unit (MMU)
299
173
* is enabled during system emulation is responsible for managing
300
174
* input/output operations. These callbacks are designed to implement
@@ -449,7 +323,7 @@ static void mmu_write_b(riscv_t *rv, const uint32_t vaddr, const uint8_t val)
449
323
* TODO: dTLB can be introduced here to
450
324
* cache the gVA to gPA tranlation.
451
325
*/
452
- static uint32_t mmu_translate (riscv_t * rv , uint32_t vaddr , bool rw )
326
+ uint32_t mmu_translate (riscv_t * rv , uint32_t vaddr , bool rw )
453
327
{
454
328
if (!rv -> csr_satp )
455
329
return vaddr ;
0 commit comments