1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/*
* Early initialization code for riscv virtual memory
*
* Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*/
#include <arch/encoding.h>
#include <stdint.h>
#include <vm.h>
/* Delegate controls which traps are delegated to the payload. If you
* wish to temporarily disable some or all delegation you can, in a
* debugger, set it to a different value (e.g. 0 to have all traps go
* to M-mode). In practice, this variable has been a lifesaver. It is
* still not quite determined which delegation might by unallowed by
* the spec so for now we enumerate and set them all. */
static int delegate = 0
| (1 << CAUSE_MISALIGNED_FETCH)
| (1 << CAUSE_FETCH_ACCESS)
| (1 << CAUSE_ILLEGAL_INSTRUCTION)
| (1 << CAUSE_BREAKPOINT)
| (1 << CAUSE_LOAD_ACCESS)
| (1 << CAUSE_STORE_ACCESS)
| (1 << CAUSE_USER_ECALL)
| (1 << CAUSE_FETCH_PAGE_FAULT)
| (1 << CAUSE_LOAD_PAGE_FAULT)
| (1 << CAUSE_STORE_PAGE_FAULT)
;
void mstatus_init(void)
{
uintptr_t ms = 0;
ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
write_csr(mstatus, ms);
// clear any pending timer interrupts.
clear_csr(mip, MIP_STIP | MIP_SSIP);
// enable machine and supervisor timer and
// all other supervisor interrupts.
set_csr(mie, MIP_MTIP | MIP_STIP | MIP_SSIP);
// Delegate supervisor timer and other interrupts
// to supervisor mode.
set_csr(mideleg, MIP_STIP | MIP_SSIP);
set_csr(medeleg, delegate);
// Enable all user/supervisor-mode counters using
// v1.10 register addresses.
// They moved from the earlier spec.
// Until we trust our toolchain use the hardcoded constants.
// These were in flux and people who get the older toolchain
// will have difficult-to-debug failures.
write_csr(/*mcounteren*/0x306, 7);
}
|