This repository has been archived by the owner on Aug 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathriscv.s
208 lines (167 loc) · 3.77 KB
/
riscv.s
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# read & write some registers
.text
.func read_mhartid
.globl read_mhartid
# uint32 read_mhartid(void);
read_mhartid:
csrr a0, mhartid
ret
.endfunc
.func read_tp
.globl read_tp
# uint32 read_tp(void);
read_tp:
mv a0, tp
ret
.endfunc
.func write_tp
.globl write_tp
# void write_tp(uint32);
write_tp:
mv tp, a0
ret
.endfunc
.func read_mie
.globl read_mie
# uint32 read_mie(void);
read_mie:
csrr a0, mie
ret
.endfunc
.func write_mie
.globl write_mie
# void write_mie(uint32);
write_mie:
csrw mie, a0
ret
.endfunc
.func read_mstatus
.globl read_mstatus
# uint32 read_mstatus(void);
read_mstatus:
csrr a0, mstatus
ret
.endfunc
.func write_mstatus
.globl write_mstatus
# void write_mstatus(uint32);
write_mstatus:
csrw mstatus, a0
ret
.endfunc
.func read_mscratch
.globl read_mscratch
# uint32 read_mscratch(void);
read_mscratch:
csrr a0, mscratch
ret
.endfunc
.func write_mscratch
.globl write_mscratch
# void write_mscratch(uint32);
write_mscratch:
csrw mscratch, a0
ret
.endfunc
# PLIC related functions
# see qemu/include/hw/riscv/virt.h
.equ PLIC, 0x0c000000
.func plic_set_priority
.globl plic_set_priority
# void plic_set_priority(uint32 irq_id, int pri_val);
# IRQ: Interrupt Request
# pri_val: priority value of interrupt source
# 0: do not interrupt
# 1: lowest priority
# 7: highest priority
plic_set_priority:
li t0, PLIC
slli a0, a0, 2
add a0, a0, t0
sw a1, 0(a0)
ret
.endfunc
.equ M_ENABLE, PLIC + 0x2000
.func plic_set_m_enable
.globl plic_set_m_enable
# void plic_set_m_enable(uint32 hartid, uint32 irq_id);
# address:
# M_ENABLE + hartid * 0x80
# value of address: 1 bit for one interrupt source
# 1 enable
# 0 disable
plic_set_m_enable:
li t0, 0x80
mul a0, a0, t0
li t0, M_ENABLE
add a0, a0, t0
li t0, 1
sll a1, t0, a1
sw a1, 0(a0)
ret
.endfunc
.equ M_THRESHOLD, PLIC + 0x200000
.func plic_set_m_threshold
.globl plic_set_m_threshold
# void plic_set_m_threshold(uint32 hartid, int thr_val);
# address:
# M_THRESHOLD + hartid * 0x1000
# any interrupt priority higher than thr_val will be handled by the hart
plic_set_m_threshold:
li t0, 0x1000
mul a0, a0, t0
li t0, M_THRESHOLD
add a0, a0, t0
sw a1, 0(a0)
ret
.endfunc
.equ M_CLAIM, PLIC + 0x200004
.func plic_m_claim
.globl plic_m_claim
# int plic_m_claim(uint32 hartid);
plic_m_claim:
li t0, 0x1000
mul a0, a0, t0
li t0, M_CLAIM
add a0, a0, t0
lw t0, 0(a0)
mv a0, t0
ret
.endfunc
.equ M_COMPLETE, M_CLAIM
.func plic_m_complete
.globl plic_m_complete
# extern void plic_m_complete(uint32 hartid, uint32 irq_id);
plic_m_complete:
li t0, 0x1000
mul a0, a0, t0
li t0, M_COMPLETE
add a0, a0, t0
sw a1, 0(a0)
ret
.endfunc
# CLINT related functions
.equ CLINT, 0x2000000
.func write_clint_msip_one
.globl write_clint_msip_one
# void write_clint_msip_one(uint32 hartid);
write_clint_msip_one:
slli a0, a0, 2 # a0 = hartid * 4
li t0, CLINT
add t0, a0, t0
li t1, 1
sw t1, 0(t0)
ret
.endfunc
.func write_clint_msip_zero
.globl write_clint_msip_zero
# extern void write_clint_msip_zero(uint32 hartid);
write_clint_msip_zero:
slli a0, a0, 2
li t0, CLINT
add t0, a0, t0
li t1, 0
sw t1, 0(t0)
ret
.endfunc
.end