xref: /kvm-unit-tests/lib/riscv/processor.c (revision 6c2108dbbf8cda8ac5d5b742eb5a49114012b8bb)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
4  */
5 #include <libcflat.h>
6 #include <asm/csr.h>
7 #include <asm/isa.h>
8 #include <asm/processor.h>
9 #include <asm/setup.h>
10 
11 extern unsigned long _text;
12 
13 void show_regs(struct pt_regs *regs)
14 {
15 	struct thread_info *info = current_thread_info();
16 	uintptr_t text = (uintptr_t)&_text;
17 	unsigned int w = __riscv_xlen / 4;
18 
19 	printf("Load address: %" PRIxPTR "\n", text);
20 	printf("CPU%3d : hartid=%lx\n", info->cpu, info->hartid);
21 	printf("status : %.*lx\n", w, regs->status);
22 	printf("cause  : %.*lx\n", w, regs->cause);
23 	printf("badaddr: %.*lx\n", w, regs->badaddr);
24 	printf("pc: %.*lx ra: %.*lx\n", w, regs->epc, w, regs->ra);
25 	printf("sp: %.*lx gp: %.*lx tp : %.*lx\n", w, regs->sp, w, regs->gp, w, regs->tp);
26 	printf("a0: %.*lx a1: %.*lx a2 : %.*lx a3 : %.*lx\n", w, regs->a0, w, regs->a1, w, regs->a2, w, regs->a3);
27 	printf("a4: %.*lx a5: %.*lx a6 : %.*lx a7 : %.*lx\n", w, regs->a4, w, regs->a5, w, regs->a6, w, regs->a7);
28 	printf("t0: %.*lx t1: %.*lx t2 : %.*lx t3 : %.*lx\n", w, regs->t0, w, regs->t1, w, regs->t2, w, regs->t3);
29 	printf("t4: %.*lx t5: %.*lx t6 : %.*lx\n", w, regs->t4, w, regs->t5, w, regs->t6);
30 	printf("s0: %.*lx s1: %.*lx s2 : %.*lx s3 : %.*lx\n", w, regs->s0, w, regs->s1, w, regs->s2, w, regs->s3);
31 	printf("s4: %.*lx s5: %.*lx s6 : %.*lx s7 : %.*lx\n", w, regs->s4, w, regs->s5, w, regs->s6, w, regs->s7);
32 	printf("s8: %.*lx s9: %.*lx s10: %.*lx s11: %.*lx\n", w, regs->s8, w, regs->s9, w, regs->s10, w, regs->s11);
33 }
34 
35 void do_handle_exception(struct pt_regs *regs)
36 {
37 	struct thread_info *info = current_thread_info();
38 
39 	assert(regs->cause < EXCEPTION_CAUSE_MAX);
40 	if (info->exception_handlers[regs->cause]) {
41 		info->exception_handlers[regs->cause](regs);
42 		return;
43 	}
44 
45 	show_regs(regs);
46 	dump_frame_stack((void *)regs->epc, (void *)regs->s0);
47 	abort();
48 }
49 
50 void install_exception_handler(unsigned long cause, void (*handler)(struct pt_regs *))
51 {
52 	struct thread_info *info = current_thread_info();
53 
54 	assert(cause < EXCEPTION_CAUSE_MAX);
55 	info->exception_handlers[cause] = handler;
56 }
57 
58 void thread_info_init(void)
59 {
60 	unsigned long hartid = csr_read(CSR_SSCRATCH);
61 	int cpu = hartid_to_cpu(hartid);
62 
63 	isa_init(&cpus[cpu]);
64 	csr_write(CSR_SSCRATCH, &cpus[cpu]);
65 }
66