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/processor.h> 8 #include <asm/setup.h> 9 10 extern unsigned long _text; 11 12 void show_regs(struct pt_regs *regs) 13 { 14 uintptr_t text = (uintptr_t)&_text; 15 unsigned int w = __riscv_xlen / 4; 16 17 printf("Load address: %" PRIxPTR "\n", text); 18 printf("status : %.*lx\n", w, regs->status); 19 printf("cause : %.*lx\n", w, regs->cause); 20 printf("badaddr: %.*lx\n", w, regs->badaddr); 21 printf("pc: %.*lx ra: %.*lx\n", w, regs->epc, w, regs->ra); 22 printf("sp: %.*lx gp: %.*lx tp : %.*lx\n", w, regs->sp, w, regs->gp, w, regs->tp); 23 printf("a0: %.*lx a1: %.*lx a2 : %.*lx a3 : %.*lx\n", w, regs->a0, w, regs->a1, w, regs->a2, w, regs->a3); 24 printf("a4: %.*lx a5: %.*lx a6 : %.*lx a7 : %.*lx\n", w, regs->a4, w, regs->a5, w, regs->a6, w, regs->a7); 25 printf("t0: %.*lx t1: %.*lx t2 : %.*lx t3 : %.*lx\n", w, regs->t0, w, regs->t1, w, regs->t2, w, regs->t3); 26 printf("t4: %.*lx t5: %.*lx t6 : %.*lx\n", w, regs->t4, w, regs->t5, w, regs->t6); 27 printf("s0: %.*lx s1: %.*lx s2 : %.*lx s3 : %.*lx\n", w, regs->s0, w, regs->s1, w, regs->s2, w, regs->s3); 28 printf("s4: %.*lx s5: %.*lx s6 : %.*lx s7 : %.*lx\n", w, regs->s4, w, regs->s5, w, regs->s6, w, regs->s7); 29 printf("s8: %.*lx s9: %.*lx s10: %.*lx s11: %.*lx\n", w, regs->s8, w, regs->s9, w, regs->s10, w, regs->s11); 30 } 31 32 void do_handle_exception(struct pt_regs *regs) 33 { 34 struct thread_info *info = current_thread_info(); 35 36 assert(regs->cause < EXCEPTION_CAUSE_MAX); 37 if (info->exception_handlers[regs->cause]) { 38 info->exception_handlers[regs->cause](regs); 39 return; 40 } 41 42 show_regs(regs); 43 assert(0); 44 } 45 46 void install_exception_handler(unsigned long cause, void (*handler)(struct pt_regs *)) 47 { 48 struct thread_info *info = current_thread_info(); 49 50 assert(cause < EXCEPTION_CAUSE_MAX); 51 info->exception_handlers[cause] = handler; 52 } 53 54 void thread_info_init(void) 55 { 56 unsigned long hartid = csr_read(CSR_SSCRATCH); 57 int cpu = hartid_to_cpu(hartid); 58 59 csr_write(CSR_SSCRATCH, &cpus[cpu]); 60 } 61