]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/thread-jdb.cpp
32420e808d9c200776563c263ed42afba42a63cf
[l4.git] / kernel / fiasco / src / kern / arm / thread-jdb.cpp
1 INTERFACE [arm-debug]:
2
3 #include "trap_state.h"
4
5 EXTENSION class Thread
6 {
7 public:
8   typedef void (*Dbg_extension_entry)(Thread *t, Entry_frame *r);
9   static Dbg_extension_entry dbg_extension[64];
10
11 private:
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;
14 };
15
16
17 //-----------------------------------------------------------------------------
18 IMPLEMENTATION [arm && debug]:
19
20 #include "kernel_task.h"
21 #include "mem_layout.h"
22 #include "mmu.h"
23
24 #include <cstring>
25
26 Thread::Dbg_extension_entry Thread::dbg_extension[64];
27
28 Trap_state::Handler Thread::nested_trap_handler FIASCO_FASTCALL;
29
30 extern "C" void sys_kdb_ke()
31 {
32   cpu_lock.lock();
33   Thread *t = current_thread();
34   unsigned *x = (unsigned*)t->regs()->ip();
35
36   if ((*x & 0xffff0000) == 0xe35e0000)
37     {
38       unsigned func = (*x) & 0x3f;
39       if (Thread::dbg_extension[func])
40         {
41           Thread::dbg_extension[func](t, t->regs());
42           t->regs()->ip(t->regs()->ip() + 4);
43           return;
44         }
45     }
46
47   char str[32] = "USER ENTRY";
48   if ((*x & 0xfffffff0) == 0xea000000)
49     // check for always branch, no return, maximum 32 bytes forward
50     {
51       strncpy(str, (char *)(x + 1), sizeof(str));
52       str[sizeof(str)-1] = 0;
53     }
54
55   kdb_ke(str);
56 }
57
58 IMPLEMENT
59 int
60 Thread::call_nested_trap_handler(Trap_state *ts)
61 {
62   unsigned phys_cpu = Proc::cpu_id();
63   unsigned log_cpu = Cpu::cpus.find_cpu(Cpu::By_phys_id(phys_cpu));
64   if (log_cpu == ~0U)
65     {
66       printf("Trap on unknown CPU phys_id=%x\n", phys_cpu);
67       log_cpu = 0;
68     }
69
70   unsigned long &ntr = nested_trap_recover.cpu(log_cpu);
71
72   void *stack = 0;
73
74   if (!ntr)
75     stack = dbg_stack.cpu(log_cpu).stack_top;
76
77   Mem_space *m = Mem_space::current_mem_space(log_cpu);
78
79   if (Kernel_task::kernel_task() != m)
80     Kernel_task::kernel_task()->make_current();
81
82   Mword dummy1, tmp, ret;
83   {
84     register Mword _ts asm("r0") = (Mword)ts;
85     register Mword _lcpu asm("r1") = log_cpu;
86
87     asm volatile(
88         "mov    %[origstack], sp         \n"
89         "ldr    %[tmp], [%[ntr]]         \n"
90         "teq    %[tmp], #0               \n"
91         "moveq  sp, %[stack]             \n"
92         "add    %[tmp], %[tmp], #1       \n"
93         "str    %[tmp], [%[ntr]]         \n"
94         "str    %[origstack], [sp, #-4]! \n"
95         "str    %[ntr], [sp, #-4]!       \n"
96         "adr    lr, 1f                   \n"
97         "mov    pc, %[handler]           \n"
98         "1:                              \n"
99         "ldr    %[ntr], [sp], #4         \n"
100         "ldr    sp, [sp]                 \n"
101         "ldr    %[tmp], [%[ntr]]         \n"
102         "sub    %[tmp], %[tmp], #1       \n"
103         "str    %[tmp], [%[ntr]]         \n"
104         : [origstack] "=&r" (dummy1), [tmp] "=&r" (tmp),
105           "=r" (_ts), "=r" (_lcpu)
106         : [ntr] "r" (&ntr), [stack] "r" (stack),
107           [handler] "r" (*nested_trap_handler),
108           "2" (_ts), "3" (_lcpu)
109         : "memory", "r2", "r3", "r4");
110
111     ret = _ts;
112   }
113
114   // the jdb-cpu might have changed things we shouldn't miss!
115   Mmu<Mem_layout::Cache_flush_area, true>::flush_cache();
116   Mem::isb();
117
118   if (m != Kernel_task::kernel_task())
119     m->make_current();
120
121   return ret;
122 }
123
124 //-----------------------------------------------------------------------------
125 IMPLEMENTATION [arm-!debug]:
126
127 extern "C" void sys_kdb_ke()
128 {}
129
130 extern "C" void enter_jdb()
131 {}