/ src / arch / riscv / virtual_memory.c
virtual_memory.c
 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  
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  }