diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 9a6374bf01..79fb99eeb3 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -935,19 +935,31 @@ void Thread::_call() void Thread::_mmu_exception() { + using namespace Genode; + using Genode::log; + _become_inactive(AWAITS_RESTART); _exception_state = MMU_FAULT; Cpu::mmu_fault(*regs, _fault); _fault.ip = regs->ip; if (_fault.type == Thread_fault::UNKNOWN) { - Genode::raw(*this, " raised unhandled MMU fault ", _fault); + Genode::warning(*this, " raised unhandled MMU fault ", _fault); return; } - if (_type != USER) - Genode::raw(*this, " raised a fault, which should never happen ", - _fault); + if (_type != USER) { + error(*this, " raised a fault, which should never happen ", + _fault); + log("Register dump: ", *regs); + log("Backtrace:"); + + Const_byte_range_ptr const stack { + (char const*)Hw::Mm::core_stack_area().base, + Hw::Mm::core_stack_area().size }; + regs->for_each_return_address(stack, [&] (void **p) { + log(*p); }); + } if (_pager && _pager->can_submit(1)) { _pager->submit(1); diff --git a/repos/base-hw/src/core/spec/arm/cpu.cc b/repos/base-hw/src/core/spec/arm/cpu.cc index 06e6f1baf5..697b9a0cf0 100644 --- a/repos/base-hw/src/core/spec/arm/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/cpu.cc @@ -22,6 +22,32 @@ using namespace Core; +void Arm_cpu::Context::print(Output &output) const +{ + using namespace Genode; + using Genode::print; + + print(output, "\n"); + print(output, " r0 = ", Hex(r0), "\n"); + print(output, " r1 = ", Hex(r1), "\n"); + print(output, " r2 = ", Hex(r2), "\n"); + print(output, " r3 = ", Hex(r3), "\n"); + print(output, " r4 = ", Hex(r4), "\n"); + print(output, " r5 = ", Hex(r5), "\n"); + print(output, " r6 = ", Hex(r6), "\n"); + print(output, " r7 = ", Hex(r7), "\n"); + print(output, " r8 = ", Hex(r8), "\n"); + print(output, " r9 = ", Hex(r9), "\n"); + print(output, " r10 = ", Hex(r10), "\n"); + print(output, " r11 = ", Hex(r11), "\n"); + print(output, " r12 = ", Hex(r12), "\n"); + print(output, " ip = ", Hex(ip), "\n"); + print(output, " sp = ", Hex(sp), "\n"); + print(output, " lr = ", Hex(lr), "\n"); + print(output, " cpsr = ", Hex(cpsr)); +} + + Arm_cpu::Context::Context(bool privileged) { using Psr = Arm_cpu::Psr; diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index ef7fabdaf5..012b04eceb 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -49,6 +49,18 @@ struct Core::Arm_cpu : public Hw::Arm_cpu struct alignas(8) Context : Cpu_state, Fpu_context { Context(bool privileged); + + void print(Output &output) const; + + void for_each_return_address(Const_byte_range_ptr const &stack, + auto const &fn) + { + void **fp = (void**)r11; + while (stack.contains(fp-1) && stack.contains(fp) && fp[0]) { + fn(fp); + fp = (void **) fp[-1]; + } + } }; /** diff --git a/repos/base-hw/src/core/spec/arm_v8/cpu.cc b/repos/base-hw/src/core/spec/arm_v8/cpu.cc index e64e9f88e9..cca9f9c59e 100644 --- a/repos/base-hw/src/core/spec/arm_v8/cpu.cc +++ b/repos/base-hw/src/core/spec/arm_v8/cpu.cc @@ -22,6 +22,22 @@ using namespace Core; +void Cpu::Context::print(Output &output) const +{ + using namespace Genode; + using Genode::print; + + print(output, "\n"); + for (unsigned i = 0; i < 31; i++) + print(output, " x", i, " = ", Hex(r[i]), "\n"); + print(output, " ip = ", Hex(ip), "\n"); + print(output, " sp = ", Hex(sp), "\n"); + print(output, " esr = ", Hex(esr_el1), "\n"); + print(output, " pstate = ", Hex(pstate), "\n"); + print(output, " mdscr = ", Hex(mdscr_el1)); +} + + Cpu::Context::Context(bool privileged) { Spsr::El::set(pstate, privileged ? 1 : 0); diff --git a/repos/base-hw/src/core/spec/arm_v8/cpu.h b/repos/base-hw/src/core/spec/arm_v8/cpu.h index e4b38183cb..b48e8bec9b 100644 --- a/repos/base-hw/src/core/spec/arm_v8/cpu.h +++ b/repos/base-hw/src/core/spec/arm_v8/cpu.h @@ -79,6 +79,18 @@ struct Core::Cpu : Hw::Arm_64_cpu Fpu_state fpu_state { }; Context(bool privileged); + + void print(Output &output) const; + + void for_each_return_address(Const_byte_range_ptr const &stack, + auto const &fn) + { + void **fp = (void**)r[29]; + while (stack.contains(fp) && stack.contains(fp + 1) && fp[1]) { + fn(fp + 1); + fp = (void **) fp[0]; + } + } }; class Mmu_context diff --git a/repos/base-hw/src/core/spec/riscv/cpu.cc b/repos/base-hw/src/core/spec/riscv/cpu.cc index df9495c743..0d58bef4a6 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.cc +++ b/repos/base-hw/src/core/spec/riscv/cpu.cc @@ -25,6 +25,47 @@ using Mmu_context = Core::Cpu::Mmu_context; using namespace Core; +void Cpu::Context::print(Output &output) const +{ + using namespace Genode; + using Genode::print; + + print(output, "\n"); + print(output, " ip = ", Hex(ip), "\n"); + print(output, " ra = ", Hex(ra), "\n"); + print(output, " sp = ", Hex(sp), "\n"); + print(output, " gp = ", Hex(gp), "\n"); + print(output, " tp = ", Hex(tp), "\n"); + print(output, " t0 = ", Hex(t0), "\n"); + print(output, " t1 = ", Hex(t1), "\n"); + print(output, " t2 = ", Hex(t2), "\n"); + print(output, " s0 = ", Hex(s0), "\n"); + print(output, " s1 = ", Hex(s1), "\n"); + print(output, " a0 = ", Hex(a0), "\n"); + print(output, " a1 = ", Hex(a1), "\n"); + print(output, " a2 = ", Hex(a2), "\n"); + print(output, " a3 = ", Hex(a3), "\n"); + print(output, " a4 = ", Hex(a4), "\n"); + print(output, " a5 = ", Hex(a5), "\n"); + print(output, " a6 = ", Hex(a6), "\n"); + print(output, " a7 = ", Hex(a7), "\n"); + print(output, " s2 = ", Hex(s2), "\n"); + print(output, " s3 = ", Hex(s3), "\n"); + print(output, " s4 = ", Hex(s4), "\n"); + print(output, " s5 = ", Hex(s5), "\n"); + print(output, " s6 = ", Hex(s6), "\n"); + print(output, " s7 = ", Hex(s7), "\n"); + print(output, " s8 = ", Hex(s8), "\n"); + print(output, " s9 = ", Hex(s9), "\n"); + print(output, " s10 = ", Hex(s10), "\n"); + print(output, " s11 = ", Hex(s11), "\n"); + print(output, " t3 = ", Hex(t3), "\n"); + print(output, " t4 = ", Hex(t4), "\n"); + print(output, " t5 = ", Hex(t5), "\n"); + print(output, " t6 = ", Hex(t6)); +} + + Cpu::Context::Context(bool) { /* diff --git a/repos/base-hw/src/core/spec/riscv/cpu.h b/repos/base-hw/src/core/spec/riscv/cpu.h index 40db57db70..4d8e1a262e 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.h +++ b/repos/base-hw/src/core/spec/riscv/cpu.h @@ -56,6 +56,11 @@ class Core::Cpu : public Hw::Riscv_cpu struct alignas(8) Context : Genode::Cpu_state { Context(bool); + + void print(Output &output) const; + + void for_each_return_address(Const_byte_range_ptr const &, + auto const &) { } }; class Mmu_context diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index 249b53e5ab..eb70a0e69a 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -37,6 +37,27 @@ struct Pseudo_descriptor } __attribute__((packed)); +void Cpu::Context::print(Output &output) const +{ + using namespace Genode; + using Genode::print; + + print(output, "\n"); + print(output, " ip = ", Hex(ip), "\n"); + print(output, " sp = ", Hex(sp), "\n"); + print(output, " cs = ", Hex(cs), "\n"); + print(output, " ss = ", Hex(ss), "\n"); + print(output, " eflags = ", Hex(eflags), "\n"); + print(output, " rax = ", Hex(rax), "\n"); + print(output, " rbx = ", Hex(rbx), "\n"); + print(output, " rcx = ", Hex(rcx), "\n"); + print(output, " rdx = ", Hex(rdx), "\n"); + print(output, " rdi = ", Hex(rdi), "\n"); + print(output, " rsi = ", Hex(rsi), "\n"); + print(output, " rbp = ", Hex(rbp)); +} + + Cpu::Context::Context(bool core) { eflags = EFLAGS_IF_SET; diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.h b/repos/base-hw/src/core/spec/x86_64/cpu.h index e612cc0321..71b4a6dc38 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/spec/x86_64/cpu.h @@ -100,6 +100,18 @@ class Core::Cpu : public Hw::X86_64_cpu }; Context(bool privileged); + + void print(Output &output) const; + + void for_each_return_address(Const_byte_range_ptr const &stack, + auto const &fn) + { + void **fp = (void**)rbp; + while (stack.contains(fp) && stack.contains(fp + 1) && fp[1]) { + fn(fp + 1); + fp = (void **) fp[0]; + } + } } __attribute__((packed));