blob: 87439559c929d76bc91dab70fee2e8c36fecb3ab (
plain)
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
|
#include "types.h"
#include "memlayout.h"
#include "riscv.h"
#include "defs.h"
void main();
// entry.S uses this as the initial stack.
__attribute__ ((aligned (16))) char stack0[4096];
// assembly code in kernelvec for machine-mode timer interrupt.
extern void machinevec();
// scratch area for timer interrupt.
uint64 mscratch0[8];
__attribute__ ((aligned (16)))
void
xyzzy()
{
uartputc('I');
}
// entry.S jumps here in machine mode on stack0.
void
mstart()
{
// set M Previous Privilege mode to Supervisor, for mret.
unsigned long x = r_mstatus();
x &= ~MSTATUS_MPP_MASK;
x |= MSTATUS_MPP_S;
w_mstatus(x);
// set M Exception Program Counter to main, for mret.
// requires gcc -mcmodel=medany
w_mepc((uint64)main);
// disable paging for now.
w_satp(0);
// delegate all interrupts and exceptions to supervisor mode.
w_medeleg(0xffff);
w_mideleg(0xffff);
// set up to receive timer interrupts in machine mode.
*(uint64*)CLINT_MTIMECMP0 = *(uint64*)CLINT_MTIME + 10000;
mscratch0[4] = CLINT_MTIMECMP0;
mscratch0[5] = 10000000;
w_mscratch((uint64)mscratch0);
w_mtvec((uint64)machinevec);
w_mstatus(r_mstatus() | MSTATUS_MIE);
w_mie(r_mie() | MIE_MTIE);
// jump to main in supervisor mode.
asm("mret");
}
|