xref: /aosp_15_r20/external/coreboot/src/arch/riscv/virtual_memory.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Early initialization code for riscv virtual memory
4  */
5 
6 #include <arch/cpu.h>
7 #include <arch/encoding.h>
8 #include <vm.h>
9 
10 /* Delegate controls which traps are delegated to the payload. If you
11  * wish to temporarily disable some or all delegation you can, in a
12  * debugger, set it to a different value (e.g. 0 to have all traps go
13  * to M-mode). In practice, this variable has been a lifesaver.  It is
14  * still not quite determined which delegation might by unallowed by
15  * the spec so for now we enumerate and set them all. */
16 static u32 delegate = 0
17 	| (1 << CAUSE_MISALIGNED_FETCH)
18 	| (1 << CAUSE_MISALIGNED_STORE)
19 	| (1 << CAUSE_MISALIGNED_LOAD)
20 	| (1 << CAUSE_FETCH_ACCESS)
21 	| (1 << CAUSE_ILLEGAL_INSTRUCTION)
22 	| (1 << CAUSE_BREAKPOINT)
23 	| (1 << CAUSE_LOAD_ACCESS)
24 	| (1 << CAUSE_STORE_ACCESS)
25 	| (1 << CAUSE_USER_ECALL)
26 	| (1 << CAUSE_FETCH_PAGE_FAULT)
27 	| (1 << CAUSE_LOAD_PAGE_FAULT)
28 	| (1 << CAUSE_STORE_PAGE_FAULT)
29 	;
30 
mstatus_init(void)31 void mstatus_init(void)
32 {
33 	// clear any pending timer interrupts.
34 	clear_csr(mip,  MIP_STIP | MIP_SSIP);
35 
36 	// enable machine and supervisor timer and
37 	// all other supervisor interrupts.
38 	set_csr(mie, MIP_MTIP | MIP_STIP | MIP_SSIP);
39 
40 	// Delegate supervisor timer and other interrupts to supervisor mode,
41 	// if supervisor mode is supported.
42 	if (supports_extension('S')) {
43 		set_csr(mideleg, MIP_STIP | MIP_SSIP);
44 		set_csr(medeleg, delegate);
45 	}
46 
47 	// Enable all user/supervisor-mode counters
48 	write_csr(mcounteren, 7);
49 }
50