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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
.extern main
.extern CONSOLE_STRICT_FLUSH
.section .text.start
.global _start
.type _start, STT_FUNC
_start:
# Have harts other than 0 spin until hart0 wakes them up. As a side
# effect, load every hart's thread pointer register with MHARTID.
csrr tp, mhartid
bnez tp, wait_for_hart0
# Set up console_strict_flush.
la t0, console_strict_flush
la t1, CONSOLE_STRICT_FLUSH
sd t0, (t1)
# Set up hart0's stack.
la sp, hart0_initial_stack_top
# Put the address of the DeviceTree into the first argument position
# for hart0_boot.
c.mv a0, a1
# The rest of this function is to get out of machine mode and into
# supervisor mode by fictitiously returning from a trap.
# First, set MSTATUS.MPP to Supervisor, so that when we execute mret,
# the privilege level will lower to Supervisor.
csrr t0, mstatus
li t1, ~(0b11 << 11)
and t0, t0, t1
li t1, (0b01 << 11)
or t0, t0, t1
csrw mstatus, t0
# Next, set MEPC to the address of hart0_boot, so that when we execute
# mret, execution will continue there.
la t0, hart0_boot
csrw mepc, t0
# Delegate all exceptions and interrupts to the Supervisor level.
li t0, 0xffff
csrw medeleg, t0
csrw mideleg, t0
# Set SATP.MODE to Bare, and clear the rest of the bits. This disables
# paging in Supervisor mode.
csrw satp, zero
# Set PMP0CFG.{R, W, X} to 1, PMP0CFG.A to TOR, and PMP0ADDR to the
# maximum value. This allows supervisor mode to access all of physical
# memory.
li t0, (0b01 << 3) | 0b111
csrw pmpcfg0, t0
li t0, -1
csrw pmpaddr0, t0
# Jump to supervisor mode.
mret
.size _start, . - _start
.section .text
.type wait_for_hart0, STT_FUNC
wait_for_hart0:
# TODO
wfi
j wait_for_hart0
.size wait_for_hart0, . - wait_for_hart0
.section .text
.type console_strict_flush, STT_FUNC
console_strict_flush:
li t0, 0x10000000
1:
c.beqz a1, 2f
lb t1, (a0)
sb t1, (t0)
addi a0, a0, 1
addi a1, a1, -1
j 1b
2:
ret
.size console_strict_flush, . - console_strict_flush
|