3 #include "trap_state.h"
8 typedef void (*Dbg_extension_entry)(Thread *t, Entry_frame *r);
9 static Dbg_extension_entry dbg_extension[64];
12 static int call_nested_trap_handler(Trap_state *ts) asm ("call_nested_trap_handler");
13 static Trap_state::Handler nested_trap_handler FIASCO_FASTCALL;
17 //-----------------------------------------------------------------------------
18 IMPLEMENTATION [arm && debug]:
20 #include "kernel_task.h"
21 #include "mem_layout.h"
26 Thread::Dbg_extension_entry Thread::dbg_extension[64];
28 Trap_state::Handler Thread::nested_trap_handler FIASCO_FASTCALL;
30 extern "C" void sys_kdb_ke()
33 Thread *t = current_thread();
34 Unsigned32 x = Thread::peek_user((Unsigned32 *)t->regs()->ip(), t);
36 if (EXPECT_FALSE(t->is_kernel_mem_op_hit_and_clear()))
39 if ((x & 0xffff0000) == 0xe35e0000)
41 unsigned func = x & 0x3f;
42 if (Thread::dbg_extension[func])
44 Thread::dbg_extension[func](t, t->regs());
45 t->regs()->ip(t->regs()->ip() + 4);
50 char str[32] = "USER ENTRY";
51 if ((x & 0xfffffff0) == 0xea000000)
52 // check for always branch, no return, maximum 32 bytes forward
54 char const *user_str = reinterpret_cast<char const *>(t->regs()->ip() + 4);
55 for (unsigned i = 0; i < sizeof(str); ++i)
57 str[i] = Thread::peek_user(user_str + i, t);
58 if (EXPECT_FALSE(t->is_kernel_mem_op_hit_and_clear()))
67 str[sizeof(str)-1] = 0;
75 Thread::call_nested_trap_handler(Trap_state *ts)
77 Cpu_phys_id phys_cpu = Proc::cpu_id();
78 Cpu_number log_cpu = Cpu::cpus.find_cpu(Cpu::By_phys_id(phys_cpu));
79 if (log_cpu == Cpu_number::nil())
81 printf("Trap on unknown CPU phys_id=%x\n",
82 cxx::int_value<Cpu_phys_id>(phys_cpu));
83 log_cpu = Cpu_number::boot_cpu();
86 unsigned long &ntr = nested_trap_recover.cpu(log_cpu);
91 stack = dbg_stack.cpu(log_cpu).stack_top;
93 Mem_space *m = Mem_space::current_mem_space(log_cpu);
95 if (Kernel_task::kernel_task() != m)
96 Kernel_task::kernel_task()->make_current();
98 Mword dummy1, tmp, ret;
100 register Mword _ts asm("r0") = (Mword)ts;
101 register Cpu_number _lcpu asm("r1") = log_cpu;
104 "mov %[origstack], sp \n"
105 "ldr %[tmp], [%[ntr]] \n"
107 "moveq sp, %[stack] \n"
108 "add %[tmp], %[tmp], #1 \n"
109 "str %[tmp], [%[ntr]] \n"
110 "str %[origstack], [sp, #-4]! \n"
111 "str %[ntr], [sp, #-4]! \n"
113 "mov pc, %[handler] \n"
115 "ldr %[ntr], [sp], #4 \n"
117 "ldr %[tmp], [%[ntr]] \n"
118 "sub %[tmp], %[tmp], #1 \n"
119 "str %[tmp], [%[ntr]] \n"
120 : [origstack] "=&r" (dummy1), [tmp] "=&r" (tmp),
121 "=r" (_ts), "=r" (_lcpu)
122 : [ntr] "r" (&ntr), [stack] "r" (stack),
123 [handler] "r" (*nested_trap_handler),
124 "2" (_ts), "3" (_lcpu)
125 : "memory", "r2", "r3", "r4");
130 // the jdb-cpu might have changed things we shouldn't miss!
131 Mmu<Mem_layout::Cache_flush_area, true>::flush_cache();
134 if (m != Kernel_task::kernel_task())
138 Cpu_call::handle_global_requests();
143 //-----------------------------------------------------------------------------
144 IMPLEMENTATION [arm-!debug]:
146 extern "C" void sys_kdb_ke()
149 PRIVATE static inline
151 Thread::call_nested_trap_handler(Trap_state *)