Message ID | 397e6741438a8b125dc53945a74a58246fac4faf.1677237653.git.oleksii.kurochko@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | RISCV basic exception handling implementation | expand |
On 24.02.2023 12:35, Oleksii Kurochko wrote: > --- a/xen/arch/riscv/traps.c > +++ b/xen/arch/riscv/traps.c > @@ -4,10 +4,95 @@ > * > * RISC-V Trap handlers > */ > + > +#include <xen/errno.h> I couldn't spot anything in the file which would require this inclusion. > +#include <xen/lib.h> > + > +#include <asm/csr.h> > +#include <asm/early_printk.h> > #include <asm/processor.h> > #include <asm/traps.h> > > -void do_trap(struct cpu_user_regs *cpu_regs) > +static const char *decode_trap_cause(unsigned long cause) > +{ > + static const char *const trap_causes[] = { > + [CAUSE_MISALIGNED_FETCH] = "Instruction Address Misaligned", > + [CAUSE_FETCH_ACCESS] = "Instruction Access Fault", > + [CAUSE_ILLEGAL_INSTRUCTION] = "Illegal Instruction", > + [CAUSE_BREAKPOINT] = "Breakpoint", > + [CAUSE_MISALIGNED_LOAD] = "Load Address Misaligned", > + [CAUSE_LOAD_ACCESS] = "Load Access Fault", > + [CAUSE_MISALIGNED_STORE] = "Store/AMO Address Misaligned", > + [CAUSE_STORE_ACCESS] = "Store/AMO Access Fault", > + [CAUSE_USER_ECALL] = "Environment Call from U-Mode", > + [CAUSE_SUPERVISOR_ECALL] = "Environment Call from S-Mode", > + [CAUSE_MACHINE_ECALL] = "Environment Call from M-Mode", > + [CAUSE_FETCH_PAGE_FAULT] = "Instruction Page Fault", > + [CAUSE_LOAD_PAGE_FAULT] = "Load Page Fault", > + [CAUSE_STORE_PAGE_FAULT] = "Store/AMO Page Fault", > + [CAUSE_FETCH_GUEST_PAGE_FAULT] = "Instruction Guest Page Fault", > + [CAUSE_LOAD_GUEST_PAGE_FAULT] = "Load Guest Page Fault", > + [CAUSE_VIRTUAL_INST_FAULT] = "Virtualized Instruction Fault", > + [CAUSE_STORE_GUEST_PAGE_FAULT] = "Guest Store/AMO Page Fault", > + }; > + > + if ( cause < ARRAY_SIZE(trap_causes) && trap_causes[cause] ) > + return trap_causes[cause]; > + return "UNKNOWN"; > +} > + > +const char *decode_reserved_interrupt_cause(unsigned long irq_cause) For any non-static function that you add you will need a declaration in a header, which the defining C file then includes. I understand that during initial bringup functions without (external) callers may want to (temporarily) exist, but briefly clarifying what the future expectation regarding external uses might help. Any function that's not expected to gain external callers should be static. Jan
On Mon, 2023-02-27 at 13:48 +0100, Jan Beulich wrote: > On 24.02.2023 12:35, Oleksii Kurochko wrote: > > --- a/xen/arch/riscv/traps.c > > +++ b/xen/arch/riscv/traps.c > > @@ -4,10 +4,95 @@ > > * > > * RISC-V Trap handlers > > */ > > + > > +#include <xen/errno.h> > > I couldn't spot anything in the file which would require this > inclusion. Sure. It can be removed. > > > +#include <xen/lib.h> > > + > > +#include <asm/csr.h> > > +#include <asm/early_printk.h> > > #include <asm/processor.h> > > #include <asm/traps.h> > > > > -void do_trap(struct cpu_user_regs *cpu_regs) > > +static const char *decode_trap_cause(unsigned long cause) > > +{ > > + static const char *const trap_causes[] = { > > + [CAUSE_MISALIGNED_FETCH] = "Instruction Address > > Misaligned", > > + [CAUSE_FETCH_ACCESS] = "Instruction Access Fault", > > + [CAUSE_ILLEGAL_INSTRUCTION] = "Illegal Instruction", > > + [CAUSE_BREAKPOINT] = "Breakpoint", > > + [CAUSE_MISALIGNED_LOAD] = "Load Address Misaligned", > > + [CAUSE_LOAD_ACCESS] = "Load Access Fault", > > + [CAUSE_MISALIGNED_STORE] = "Store/AMO Address Misaligned", > > + [CAUSE_STORE_ACCESS] = "Store/AMO Access Fault", > > + [CAUSE_USER_ECALL] = "Environment Call from U-Mode", > > + [CAUSE_SUPERVISOR_ECALL] = "Environment Call from S-Mode", > > + [CAUSE_MACHINE_ECALL] = "Environment Call from M-Mode", > > + [CAUSE_FETCH_PAGE_FAULT] = "Instruction Page Fault", > > + [CAUSE_LOAD_PAGE_FAULT] = "Load Page Fault", > > + [CAUSE_STORE_PAGE_FAULT] = "Store/AMO Page Fault", > > + [CAUSE_FETCH_GUEST_PAGE_FAULT] = "Instruction Guest Page > > Fault", > > + [CAUSE_LOAD_GUEST_PAGE_FAULT] = "Load Guest Page Fault", > > + [CAUSE_VIRTUAL_INST_FAULT] = "Virtualized Instruction > > Fault", > > + [CAUSE_STORE_GUEST_PAGE_FAULT] = "Guest Store/AMO Page > > Fault", > > + }; > > + > > + if ( cause < ARRAY_SIZE(trap_causes) && trap_causes[cause] ) > > + return trap_causes[cause]; > > + return "UNKNOWN"; > > +} > > + > > +const char *decode_reserved_interrupt_cause(unsigned long > > irq_cause) > > For any non-static function that you add you will need a declaration > in a header, which the defining C file then includes. I understand > that during initial bringup functions without (external) callers may > want to (temporarily) exist, but briefly clarifying what the future > expectation regarding external uses might help. Any function that's > not expected to gain external callers should be static. Thanks. For explanation. I'll make them static. ~ Oleksii
On Mon, 2023-02-27 at 13:48 +0100, Jan Beulich wrote: > On 24.02.2023 12:35, Oleksii Kurochko wrote: > > --- a/xen/arch/riscv/traps.c > > +++ b/xen/arch/riscv/traps.c > > @@ -4,10 +4,95 @@ > > * > > * RISC-V Trap handlers > > */ > > + > > +#include <xen/errno.h> > > I couldn't spot anything in the file which would require this > inclusion. -EINVAL, -ENOENT are used in do_bug_frame() I missed that when wrote previous answer on e-mail.
On Wed, 2023-03-01 at 11:41 +0200, Oleksii wrote: > On Mon, 2023-02-27 at 13:48 +0100, Jan Beulich wrote: > > On 24.02.2023 12:35, Oleksii Kurochko wrote: > > > --- a/xen/arch/riscv/traps.c > > > +++ b/xen/arch/riscv/traps.c > > > @@ -4,10 +4,95 @@ > > > * > > > * RISC-V Trap handlers > > > */ > > > + > > > +#include <xen/errno.h> > > > > I couldn't spot anything in the file which would require this > > inclusion. > -EINVAL, -ENOENT are used in do_bug_frame() I missed that when wrote > previous answer on e-mail. Sorry for confusion. I resolved merge conflicts after rebase so <xen/errno.h> should be remove as anything is used in traps.c from it ~ Oleksii
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c index ccd3593f5a..29b1a0dfae 100644 --- a/xen/arch/riscv/traps.c +++ b/xen/arch/riscv/traps.c @@ -4,10 +4,95 @@ * * RISC-V Trap handlers */ + +#include <xen/errno.h> +#include <xen/lib.h> + +#include <asm/csr.h> +#include <asm/early_printk.h> #include <asm/processor.h> #include <asm/traps.h> -void do_trap(struct cpu_user_regs *cpu_regs) +static const char *decode_trap_cause(unsigned long cause) +{ + static const char *const trap_causes[] = { + [CAUSE_MISALIGNED_FETCH] = "Instruction Address Misaligned", + [CAUSE_FETCH_ACCESS] = "Instruction Access Fault", + [CAUSE_ILLEGAL_INSTRUCTION] = "Illegal Instruction", + [CAUSE_BREAKPOINT] = "Breakpoint", + [CAUSE_MISALIGNED_LOAD] = "Load Address Misaligned", + [CAUSE_LOAD_ACCESS] = "Load Access Fault", + [CAUSE_MISALIGNED_STORE] = "Store/AMO Address Misaligned", + [CAUSE_STORE_ACCESS] = "Store/AMO Access Fault", + [CAUSE_USER_ECALL] = "Environment Call from U-Mode", + [CAUSE_SUPERVISOR_ECALL] = "Environment Call from S-Mode", + [CAUSE_MACHINE_ECALL] = "Environment Call from M-Mode", + [CAUSE_FETCH_PAGE_FAULT] = "Instruction Page Fault", + [CAUSE_LOAD_PAGE_FAULT] = "Load Page Fault", + [CAUSE_STORE_PAGE_FAULT] = "Store/AMO Page Fault", + [CAUSE_FETCH_GUEST_PAGE_FAULT] = "Instruction Guest Page Fault", + [CAUSE_LOAD_GUEST_PAGE_FAULT] = "Load Guest Page Fault", + [CAUSE_VIRTUAL_INST_FAULT] = "Virtualized Instruction Fault", + [CAUSE_STORE_GUEST_PAGE_FAULT] = "Guest Store/AMO Page Fault", + }; + + if ( cause < ARRAY_SIZE(trap_causes) && trap_causes[cause] ) + return trap_causes[cause]; + return "UNKNOWN"; +} + +const char *decode_reserved_interrupt_cause(unsigned long irq_cause) +{ + switch ( irq_cause ) + { + case IRQ_M_SOFT: + return "M-mode Software Interrupt"; + case IRQ_M_TIMER: + return "M-mode TIMER Interrupt"; + case IRQ_M_EXT: + return "M-mode External Interrupt"; + default: + return "UNKNOWN IRQ type"; + } +} + +const char *decode_interrupt_cause(unsigned long cause) +{ + unsigned long irq_cause = cause & ~CAUSE_IRQ_FLAG; + + switch ( irq_cause ) + { + case IRQ_S_SOFT: + return "Supervisor Software Interrupt"; + case IRQ_S_TIMER: + return "Supervisor Timer Interrupt"; + case IRQ_S_EXT: + return "Supervisor External Interrupt"; + default: + return decode_reserved_interrupt_cause(irq_cause); + } +} + +const char *decode_cause(unsigned long cause) +{ + if ( cause & CAUSE_IRQ_FLAG ) + return decode_interrupt_cause(cause); + + return decode_trap_cause(cause); +} + +static void do_unexpected_trap(const struct cpu_user_regs *regs) { + unsigned long cause = csr_read(CSR_SCAUSE); + + early_printk("Unhandled exception: "); + early_printk(decode_cause(cause)); + early_printk("\n"); + die(); } + +void do_trap(struct cpu_user_regs *cpu_regs) +{ + do_unexpected_trap(cpu_regs); +}
The patch introduces stuff needed to decode a reason of an exception. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- Changes in V4: - fix string in decode_reserved_interrupt_cause() --- Changes in V3: - Nothing changed --- Changes in V2: - Make decode_trap_cause() more optimization friendly. - Merge the pathc which introduces do_unexpected_trap() to the current one. --- xen/arch/riscv/traps.c | 87 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-)