github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/riscv/exception.go (about) 1 // RISC-V processor support 2 // https://github.com/usbarmory/tamago 3 // 4 // Copyright (c) WithSecure Corporation 5 // https://foundry.withsecure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 package riscv 11 12 import ( 13 "unsafe" 14 ) 15 16 // RISC-V exception codes (non-interrupt) 17 // (Table 3.6 - Volume II: RISC-V Privileged Architectures V20211203). 18 const ( 19 InstructionAddressMisaligned = 0 20 InstructionAccessFault = 1 21 IllegalInstruction = 2 22 Breakpoint = 3 23 LoadAddressMisaligned = 4 24 LoadAccessFault = 5 25 StoreAddressMisaligned = 6 26 StoreAccessFault = 7 27 EnvironmentCallFromU = 8 28 EnvironmentCallFromS = 9 29 EnvironmentCallFromM = 11 30 InstructionPageFault = 12 31 LoadPageFault = 13 32 StorePageFault = 15 33 ) 34 35 // defined in exception.s 36 func set_mtvec(addr uint64) 37 func set_stvec(addr uint64) 38 func read_mepc() uint64 39 func read_sepc() uint64 40 func read_mcause() uint64 41 func read_scause() uint64 42 43 type ExceptionHandler func() 44 45 func vector(fn ExceptionHandler) uint64 { 46 return **((**uint64)(unsafe.Pointer(&fn))) 47 } 48 49 // DefaultExceptionHandler handles an exception by printing the exception 50 // program counter and trap cause before panicking. 51 func DefaultExceptionHandler() { 52 mcause := read_mcause() 53 size := XLEN - 1 54 55 irq := int(mcause >> size) 56 code := int(mcause) & ^(1 << size) 57 58 print("machine exception: pc ", int(read_mepc()), " interrupt ", irq, " code ", code, "\n") 59 panic("unhandled exception") 60 } 61 62 // DefaultSupervisorExceptionHandler handles an exception by printing the 63 // exception program counter and trap cause before panicking. 64 func DefaultSupervisorExceptionHandler() { 65 scause := read_scause() 66 size := XLEN - 1 67 68 irq := int(scause >> size) 69 code := int(scause) & ^(1 << size) 70 71 print("supervisor exception: pc ", int(read_sepc()), " interrupt ", irq, " code ", code, "\n") 72 panic("unhandled exception") 73 } 74 75 //go:nosplit 76 func (cpu *CPU) initExceptionHandler() { 77 set_mtvec(vector(DefaultExceptionHandler)) 78 } 79 80 // SetExceptionHandler updates the CPU machine trap vector vector with the 81 // address of the argument function. 82 func (cpu *CPU) SetExceptionHandler(fn ExceptionHandler) { 83 set_mtvec(vector(fn)) 84 } 85 86 // SetSupervisorExceptionHandler updates the CPU supervisor trap vector vector 87 // with the address of the argument function. 88 func (cpu *CPU) SetSupervisorExceptionHandler(fn ExceptionHandler) { 89 set_stvec(vector(fn)) 90 }