Sun Nov 1 21:09:48 2020 UTC ()
Update CAUSE_* defines to reflect riscv-privileged-20190608.pdf


(skrll)
diff -r1.5 -r1.6 src/sys/arch/riscv/include/sysreg.h
diff -r1.9 -r1.10 src/sys/arch/riscv/riscv/trap.c

cvs diff -r1.5 -r1.6 src/sys/arch/riscv/include/sysreg.h (expand / switch to unified diff)

--- src/sys/arch/riscv/include/sysreg.h 2020/03/14 16:12:16 1.5
+++ src/sys/arch/riscv/include/sysreg.h 2020/11/01 21:09:48 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sysreg.h,v 1.5 2020/03/14 16:12:16 skrll Exp $ */ 1/* $NetBSD: sysreg.h,v 1.6 2020/11/01 21:09:48 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -145,38 +145,44 @@ riscvreg_status_clear(uint32_t __mask) @@ -145,38 +145,44 @@ riscvreg_status_clear(uint32_t __mask)
145static inline uint32_t 145static inline uint32_t
146riscvreg_status_set(uint32_t __mask) 146riscvreg_status_set(uint32_t __mask)
147{ 147{
148 uint32_t __sr; 148 uint32_t __sr;
149 if (__builtin_constant_p(__mask) && __mask < 0x20) { 149 if (__builtin_constant_p(__mask) && __mask < 0x20) {
150 __asm("csrrsi\t%0, sstatus, %1" : "=r"(__sr) : "i"(__mask)); 150 __asm("csrrsi\t%0, sstatus, %1" : "=r"(__sr) : "i"(__mask));
151 } else { 151 } else {
152 __asm("csrrs\t%0, sstatus, %1" : "=r"(__sr) : "r"(__mask)); 152 __asm("csrrs\t%0, sstatus, %1" : "=r"(__sr) : "r"(__mask));
153 } 153 }
154 return __sr; 154 return __sr;
155} 155}
156 156
157// Cause register 157// Cause register
158#define CAUSE_MISALIGNED_FETCH 0 158#define CAUSE_FETCH_MISALIGNED 0
159#define CAUSE_FAULT_FETCH 1 159#define CAUSE_FETCH_ACCESS 1
160#define CAUSE_ILLEGAL_INSTRUCTION 2 160#define CAUSE_ILLEGAL_INSTRUCTION 2
161#define CAUSE_PRIVILEGED_INSTRUCTION 3 161#define CAUSE_BREAKPOINT 3
162#define CAUSE_MISALIGNED_LOAD 4 162#define CAUSE_LOAD_MISALIGNED 4
163#define CAUSE_FAULT_LOAD 5 163#define CAUSE_LOAD_ACCESS 5
164#define CAUSE_MISALIGNED_STORE 6 164#define CAUSE_STORE_MISALIGNED 6
165#define CAUSE_FAULT_STORE 7 165#define CAUSE_STORE_ACCESS 7
166#define CAUSE_SYSCALL 8 166#define CAUSE_SYSCALL 8
167#define CAUSE_BREAKPOINT 9 167#define CAUSE_USER_ECALL 8
168#define CAUSE_FP_DISABLED 10 168#define CAUSE_SUPERVISOR_ECALL 9
169#define CAUSE_ACCELERATOR_DISABLED 12 169/* 10 is reserved */
 170#define CAUSE_MACHINE_ECALL 11
 171#define CAUSE_FETCH_PAGE_FAULT 12
 172#define CAUSE_LOAD_PAGE_FAULT 13
 173/* 14 is Reserved */
 174#define CAUSE_STORE_PAGE_FAULT 15
 175/* >= 16 is reserved */
170 176
171static inline uint64_t 177static inline uint64_t
172riscvreg_cycle_read(void) 178riscvreg_cycle_read(void)
173{ 179{
174#ifdef _LP64 180#ifdef _LP64
175 uint64_t __lo; 181 uint64_t __lo;
176 __asm __volatile("csrr\t%0, cycle" : "=r"(__lo)); 182 __asm __volatile("csrr\t%0, cycle" : "=r"(__lo));
177 return __lo; 183 return __lo;
178#else 184#else
179 uint32_t __hi0, __hi1, __lo0; 185 uint32_t __hi0, __hi1, __lo0;
180 do { 186 do {
181 __asm __volatile( 187 __asm __volatile(
182 "csrr\t%[__hi0], cycleh" 188 "csrr\t%[__hi0], cycleh"

cvs diff -r1.9 -r1.10 src/sys/arch/riscv/riscv/trap.c (expand / switch to unified diff)

--- src/sys/arch/riscv/riscv/trap.c 2020/11/01 21:06:22 1.9
+++ src/sys/arch/riscv/riscv/trap.c 2020/11/01 21:09:48 1.10
@@ -22,61 +22,58 @@ @@ -22,61 +22,58 @@
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31 31
32#define __PMAP_PRIVATE 32#define __PMAP_PRIVATE
33#define __UFETCHSTORE_PRIVATE 33#define __UFETCHSTORE_PRIVATE
34 34
35__RCSID("$NetBSD: trap.c,v 1.9 2020/11/01 21:06:22 skrll Exp $"); 35__RCSID("$NetBSD: trap.c,v 1.10 2020/11/01 21:09:48 skrll Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/atomic.h> 39#include <sys/atomic.h>
40 40
41#include <sys/signal.h> 41#include <sys/signal.h>
42#include <sys/signalvar.h> 42#include <sys/signalvar.h>
43#include <sys/siginfo.h> 43#include <sys/siginfo.h>
44 44
45#include <uvm/uvm.h> 45#include <uvm/uvm.h>
46 46
47#include <riscv/locore.h> 47#include <riscv/locore.h>
48 48
49#define INSTRUCTION_TRAP_MASK (__BIT(CAUSE_PRIVILEGED_INSTRUCTION) \ 49#define INSTRUCTION_TRAP_MASK (__BIT(CAUSE_ILLEGAL_INSTRUCTION))
50 |__BIT(CAUSE_ILLEGAL_INSTRUCTION)) 
51 50
52#define FAULT_TRAP_MASK (__BIT(CAUSE_FAULT_FETCH) \ 51#define FAULT_TRAP_MASK (__BIT(CAUSE_FETCH_ACCESS) \
53 |__BIT(CAUSE_FAULT_LOAD) \ 52 |__BIT(CAUSE_LOAD_ACCESS) \
54 |__BIT(CAUSE_FAULT_STORE)) 53 |__BIT(CAUSE_STORE_ACCESS))
55 54
56#define MISALIGNED_TRAP_MASK (__BIT(CAUSE_MISALIGNED_FETCH) \ 55#define MISALIGNED_TRAP_MASK (__BIT(CAUSE_FETCH_MISALIGNED) \
57 |__BIT(CAUSE_MISALIGNED_LOAD) \ 56 |__BIT(CAUSE_LOAD_MISALIGNED) \
58 |__BIT(CAUSE_MISALIGNED_STORE)) 57 |__BIT(CAUSE_STORE_MISALIGNED))
59 58
60static const char * const causenames[] = { 59static const char * const causenames[] = {
61 [CAUSE_MISALIGNED_FETCH] = "misaligned fetch", 60 [CAUSE_FETCH_MISALIGNED] = "misaligned fetch",
62 [CAUSE_MISALIGNED_LOAD] = "misaligned load", 61 [CAUSE_LOAD_MISALIGNED] = "misaligned load",
63 [CAUSE_MISALIGNED_STORE] = "misaligned store", 62 [CAUSE_STORE_MISALIGNED] = "misaligned store",
64 [CAUSE_FAULT_FETCH] = "fetch", 63 [CAUSE_FETCH_ACCESS] = "fetch",
65 [CAUSE_FAULT_LOAD] = "load", 64 [CAUSE_LOAD_ACCESS] = "load",
66 [CAUSE_FAULT_STORE] = "store", 65 [CAUSE_STORE_ACCESS] = "store",
67 [CAUSE_FP_DISABLED] = "fp disabled", 
68 [CAUSE_ILLEGAL_INSTRUCTION] = "illegal instruction", 66 [CAUSE_ILLEGAL_INSTRUCTION] = "illegal instruction",
69 [CAUSE_PRIVILEGED_INSTRUCTION] = "privileged instruction", 
70 [CAUSE_BREAKPOINT] = "breakpoint", 67 [CAUSE_BREAKPOINT] = "breakpoint",
71}; 68};
72 69
73void 70void
74cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb) 71cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb)
75{ 72{
76 tf->tf_a0 = fb->fb_reg[FB_A0]; 73 tf->tf_a0 = fb->fb_reg[FB_A0];
77 tf->tf_ra = fb->fb_reg[FB_RA]; 74 tf->tf_ra = fb->fb_reg[FB_RA];
78 tf->tf_s0 = fb->fb_reg[FB_S0]; 75 tf->tf_s0 = fb->fb_reg[FB_S0];
79 tf->tf_s1 = fb->fb_reg[FB_S1]; 76 tf->tf_s1 = fb->fb_reg[FB_S1];
80 tf->tf_s2 = fb->fb_reg[FB_S2]; 77 tf->tf_s2 = fb->fb_reg[FB_S2];
81 tf->tf_s3 = fb->fb_reg[FB_S3]; 78 tf->tf_s3 = fb->fb_reg[FB_S3];
82 tf->tf_s4 = fb->fb_reg[FB_S4]; 79 tf->tf_s4 = fb->fb_reg[FB_S4];
@@ -210,31 +207,31 @@ trap_ksi_init(ksiginfo_t *ksi, int signo @@ -210,31 +207,31 @@ trap_ksi_init(ksiginfo_t *ksi, int signo
210 207
211static void 208static void
212cpu_trapsignal(struct trapframe *tf, ksiginfo_t *ksi) 209cpu_trapsignal(struct trapframe *tf, ksiginfo_t *ksi)
213{ 210{
214 if (cpu_printfataltraps) { 211 if (cpu_printfataltraps) {
215 dump_trapframe(tf, printf); 212 dump_trapframe(tf, printf);
216 } 213 }
217 (*curlwp->l_proc->p_emul->e_trapsignal)(curlwp, ksi); 214 (*curlwp->l_proc->p_emul->e_trapsignal)(curlwp, ksi);
218} 215}
219 216
220static inline vm_prot_t 217static inline vm_prot_t
221get_faulttype(register_t cause) 218get_faulttype(register_t cause)
222{ 219{
223 if (cause == CAUSE_FAULT_LOAD) 220 if (cause == CAUSE_LOAD_ACCESS)
224 return VM_PROT_READ; 221 return VM_PROT_READ;
225 if (cause == CAUSE_FAULT_STORE) 222 if (cause == CAUSE_STORE_ACCESS)
226 return VM_PROT_READ | VM_PROT_WRITE; 223 return VM_PROT_READ | VM_PROT_WRITE;
227 KASSERT(cause == CAUSE_FAULT_FETCH); 224 KASSERT(cause == CAUSE_FETCH_ACCESS);
228 return VM_PROT_READ | VM_PROT_EXECUTE; 225 return VM_PROT_READ | VM_PROT_EXECUTE;
229} 226}
230 227
231static bool 228static bool
232trap_pagefault_fixup(struct trapframe *tf, struct pmap *pmap, register_t cause, 229trap_pagefault_fixup(struct trapframe *tf, struct pmap *pmap, register_t cause,
233 intptr_t addr) 230 intptr_t addr)
234{ 231{
235 pt_entry_t * const ptep = pmap_pte_lookup(pmap, addr); 232 pt_entry_t * const ptep = pmap_pte_lookup(pmap, addr);
236 struct vm_page *pg; 233 struct vm_page *pg;
237 234
238 if (ptep == NULL) 235 if (ptep == NULL)
239 return false; 236 return false;
240 237
@@ -246,32 +243,32 @@ trap_pagefault_fixup(struct trapframe *t @@ -246,32 +243,32 @@ trap_pagefault_fixup(struct trapframe *t
246 return false; 243 return false;
247 244
248 pg = PHYS_TO_VM_PAGE(pte_to_paddr(opte)); 245 pg = PHYS_TO_VM_PAGE(pte_to_paddr(opte));
249 if (pg == NULL) 246 if (pg == NULL)
250 return false; 247 return false;
251 248
252 attr = 0; 249 attr = 0;
253 npte = opte; 250 npte = opte;
254 if ((npte & PTE_V) == 0) { 251 if ((npte & PTE_V) == 0) {
255 npte |= PTE_V; 252 npte |= PTE_V;
256 attr |= VM_PAGEMD_REFERENCED; 253 attr |= VM_PAGEMD_REFERENCED;
257 } 254 }
258#if 0 /* XXX Outdated */ 255#if 0 /* XXX Outdated */
259 if (cause == CAUSE_FAULT_STORE) { 256 if (cause == CAUSE_STORE_ACCESS) {
260 if ((npte & PTE_NW) != 0) { 257 if ((npte & PTE_NW) != 0) {
261 npte &= ~PTE_NW; 258 npte &= ~PTE_NW;
262 attr |= VM_PAGEMD_MODIFIED; 259 attr |= VM_PAGEMD_MODIFIED;
263 } 260 }
264 } else if (cause == CAUSE_FAULT_FETCH) { 261 } else if (cause == CAUSE_FETCH_ACCESS) {
265 if ((npte & PTE_NX) != 0) { 262 if ((npte & PTE_NX) != 0) {
266 npte &= ~PTE_NX; 263 npte &= ~PTE_NX;
267 attr |= VM_PAGEMD_EXECPAGE; 264 attr |= VM_PAGEMD_EXECPAGE;
268 } 265 }
269 } 266 }
270#endif 267#endif
271 if (attr == 0) 268 if (attr == 0)
272 return false; 269 return false;
273 270
274 } while (opte != atomic_cas_pte(ptep, opte, npte)); 271 } while (opte != atomic_cas_pte(ptep, opte, npte));
275 272
276 pmap_page_set_attributes(VM_PAGE_TO_MD(pg), attr); 273 pmap_page_set_attributes(VM_PAGE_TO_MD(pg), attr);
277 pmap_tlb_update_addr(pmap, addr, npte, 0); 274 pmap_tlb_update_addr(pmap, addr, npte, 0);
@@ -339,29 +336,28 @@ trap_pagefault(struct trapframe *tf, reg @@ -339,29 +336,28 @@ trap_pagefault(struct trapframe *tf, reg
339 336
340 if (fb == NULL) { 337 if (fb == NULL) {
341 return false; 338 return false;
342 } 339 }
343 340
344 cpu_jump_onfault(tf, fb); 341 cpu_jump_onfault(tf, fb);
345 return true; 342 return true;
346} 343}
347 344
348static bool 345static bool
349trap_instruction(struct trapframe *tf, register_t epc, register_t status, 346trap_instruction(struct trapframe *tf, register_t epc, register_t status,
350 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi) 347 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi)
351{ 348{
352 const bool prvopc_p = (cause == CAUSE_PRIVILEGED_INSTRUCTION); 
353 if (usertrap_p) { 349 if (usertrap_p) {
354 trap_ksi_init(ksi, SIGILL, prvopc_p ? ILL_PRVOPC : ILL_ILLOPC, 350 trap_ksi_init(ksi, SIGILL, ILL_ILLOPC,
355 (intptr_t)badaddr, cause); 351 (intptr_t)badaddr, cause);
356 } 352 }
357 return false; 353 return false;
358} 354}
359 355
360static bool 356static bool
361trap_misalignment(struct trapframe *tf, register_t epc, register_t status, 357trap_misalignment(struct trapframe *tf, register_t epc, register_t status,
362 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi) 358 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi)
363{ 359{
364 if (usertrap_p) { 360 if (usertrap_p) {
365 trap_ksi_init(ksi, SIGBUS, BUS_ADRALN, 361 trap_ksi_init(ksi, SIGBUS, BUS_ADRALN,
366 (intptr_t)badaddr, cause); 362 (intptr_t)badaddr, cause);
367 } 363 }
@@ -385,32 +381,34 @@ cpu_trap(struct trapframe *tf, register_ @@ -385,32 +381,34 @@ cpu_trap(struct trapframe *tf, register_
385 // about it. See 381 // about it. See
386 struct pmap * const pmap = curlwp->l_proc->p_vmspace->vm_map.pmap; 382 struct pmap * const pmap = curlwp->l_proc->p_vmspace->vm_map.pmap;
387 if ((intptr_t) addr < 0 383 if ((intptr_t) addr < 0
388 && pmap != pmap_kernel() 384 && pmap != pmap_kernel()
389 && pmap_pdetab_fixup(pmap, addr)) { 385 && pmap_pdetab_fixup(pmap, addr)) {
390 return; 386 return;
391 } 387 }
392#endif 388#endif
393 ok = trap_pagefault(tf, epc, status, cause, addr, 389 ok = trap_pagefault(tf, epc, status, cause, addr,
394 usertrap_p, &ksi); 390 usertrap_p, &ksi);
395 } else if (fault_mask & INSTRUCTION_TRAP_MASK) { 391 } else if (fault_mask & INSTRUCTION_TRAP_MASK) {
396 ok = trap_instruction(tf, epc, status, cause, addr, 392 ok = trap_instruction(tf, epc, status, cause, addr,
397 usertrap_p, &ksi); 393 usertrap_p, &ksi);
 394#if 0
398 } else if (fault_mask && __BIT(CAUSE_FP_DISABLED)) { 395 } else if (fault_mask && __BIT(CAUSE_FP_DISABLED)) {
399 if (!usertrap_p) { 396 if (!usertrap_p) {
400 panic("%s: fp used @ %#"PRIxREGISTER" in kernel!", 397 panic("%s: fp used @ %#"PRIxREGISTER" in kernel!",
401 __func__, tf->tf_pc); 398 __func__, tf->tf_pc);
402 } 399 }
403 fpu_load(); 400 fpu_load();
 401#endif
404 } else if (fault_mask & MISALIGNED_TRAP_MASK) { 402 } else if (fault_mask & MISALIGNED_TRAP_MASK) {
405 ok = trap_misalignment(tf, epc, status, cause, addr, 403 ok = trap_misalignment(tf, epc, status, cause, addr,
406 usertrap_p, &ksi); 404 usertrap_p, &ksi);
407 } else { 405 } else {
408 dump_trapframe(tf, printf); 406 dump_trapframe(tf, printf);
409 panic("%s: unknown kernel trap", __func__); 407 panic("%s: unknown kernel trap", __func__);
410 } 408 }
411 409
412 if (usertrap_p) { 410 if (usertrap_p) {
413 if (!ok) 411 if (!ok)
414 cpu_trapsignal(tf, &ksi); 412 cpu_trapsignal(tf, &ksi);
415 userret(curlwp); 413 userret(curlwp);
416 } else if (!ok) { 414 } else if (!ok) {