]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/arm/jdb-arm.cpp
update
[l4.git] / kernel / fiasco / src / jdb / arm / jdb-arm.cpp
1 IMPLEMENTATION [arm]:
2
3 #include "globals.h"
4 #include "kernel_task.h"
5 #include "kmem_alloc.h"
6 #include "kmem_space.h"
7 #include "space.h"
8 #include "mem_layout.h"
9 #include "mem_unit.h"
10 #include "static_init.h"
11
12
13 STATIC_INITIALIZE_P(Jdb, JDB_INIT_PRIO);
14
15 static Per_cpu<Proc::Status> DEFINE_PER_CPU jdb_irq_state;
16
17 // disable interrupts before entering the kernel debugger
18 IMPLEMENT
19 void
20 Jdb::save_disable_irqs(unsigned cpu)
21 {
22   jdb_irq_state.cpu(cpu) = Proc::cli_save();
23 }
24
25 // restore interrupts after leaving the kernel debugger
26 IMPLEMENT
27 void
28 Jdb::restore_irqs(unsigned cpu)
29 {
30   Proc::sti_restore(jdb_irq_state.cpu(cpu));
31 }
32
33 IMPLEMENT inline
34 void
35 Jdb::enter_trap_handler(unsigned /*cpu*/)
36 {}
37
38 IMPLEMENT inline
39 void
40 Jdb::leave_trap_handler(unsigned /*cpu*/)
41 {}
42
43 PROTECTED static inline
44 void
45 Jdb::monitor_address(unsigned, void *)
46 {}
47
48 IMPLEMENT inline
49 bool
50 Jdb::handle_conditional_breakpoint(unsigned /*cpu*/)
51 { return false; }
52
53 IMPLEMENT
54 void
55 Jdb::handle_nested_trap(Jdb_entry_frame *e)
56 {
57   printf("Trap in JDB: IP:%08lx PSR=%08lx ERR=%08lx\n",
58          e->ip(), e->psr, e->error_code);
59 }
60
61 IMPLEMENT
62 bool
63 Jdb::handle_debug_traps(unsigned cpu)
64 {
65   Jdb_entry_frame *ef = entry_frame.cpu(cpu);
66
67   if (ef->error_code == 0x00e00000)
68     snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s",
69              (char const *)ef->r[0]);
70   else if (ef->debug_ipi())
71     snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)),
72              "IPI ENTRY");
73
74   return true;
75 }
76
77 IMPLEMENT inline
78 bool
79 Jdb::handle_user_request(unsigned cpu)
80 {
81   Jdb_entry_frame *ef = Jdb::entry_frame.cpu(cpu);
82   const char *str = (char const *)ef->r[0];
83   Space * task = get_task(cpu);
84   char tmp;
85
86   if (ef->debug_ipi())
87     return cpu != 0;
88
89   if (ef->error_code == 0x00e00001)
90     return execute_command_ni(task, str);
91
92   if (!peek(str, task, tmp) || tmp != '*')
93     return false;
94   if (!peek(str+1, task, tmp) || tmp != '#')
95     return false;
96
97   return execute_command_ni(task, str+2);
98 }
99
100 IMPLEMENT inline
101 bool
102 Jdb::test_checksums()
103 { return true; }
104
105 static
106 bool
107 Jdb::handle_special_cmds(int)
108 { return 1; }
109
110 PUBLIC static
111 FIASCO_INIT FIASCO_NOINLINE void
112 Jdb::init()
113 {
114   static Jdb_handler enter(at_jdb_enter);
115   static Jdb_handler leave(at_jdb_leave);
116
117   Jdb::jdb_enter.add(&enter);
118   Jdb::jdb_leave.add(&leave);
119
120   Thread::nested_trap_handler = (Trap_state::Handler)enter_jdb;
121
122   Kconsole::console()->register_console(push_cons());
123 }
124
125
126 PRIVATE static
127 void *
128 Jdb::access_mem_task(Address virt, Space * task)
129 {
130   // align
131   virt &= ~0x03;
132
133   Address phys;
134
135   if (!task)
136     {
137       if (Mem_layout::in_kernel(virt))
138         {
139           Pte p = Kmem_space::kdir()->walk((void *)virt, 0, false,0);
140           if (!p.valid())
141             return 0;
142
143           phys = p.phys((void*)virt);
144         }
145       else
146         phys = virt;
147     }
148   else
149     {
150       phys = Address(task->mem_space()->virt_to_phys(virt));
151
152
153       if (phys == (Address)-1)
154         phys = task->mem_space()->virt_to_phys_s0((void *)virt);
155
156       if (phys == (Address)-1)
157         return 0;
158     }
159
160   unsigned long addr = Mem_layout::phys_to_pmem(phys);
161   if (addr == (Address)-1)
162     {
163       Mem_unit::flush_vdcache();
164       Pte pte = Kernel_task::kernel_task()->mem_space()->_dir->walk
165         ((void*)Mem_layout::Jdb_tmp_map_area, 0, false, 0);
166
167       if (pte.phys() != (phys & ~(Config::SUPERPAGE_SIZE - 1)))
168         pte.set(phys & ~(Config::SUPERPAGE_SIZE - 1), Config::SUPERPAGE_SIZE,
169                 Mem_page_attr(Page::KERN_RW | Page::CACHEABLE), true);
170
171       Mem_unit::dtlb_flush();
172
173       addr = Mem_layout::Jdb_tmp_map_area + (phys & (Config::SUPERPAGE_SIZE - 1));
174     }
175
176   return (Mword*)addr;
177 }
178
179 PUBLIC static
180 Space *
181 Jdb::translate_task(Address addr, Space * task)
182 {
183   return (Kmem::is_kmem_page_fault(addr, 0)) ? 0 : task;
184 }
185
186 PUBLIC static
187 int
188 Jdb::peek_task(Address virt, Space * task, void *value, int width)
189 {
190   void const *mem = access_mem_task(virt, task);
191   if (!mem)
192     return -1;
193
194   switch (width)
195     {
196     case 1:
197         {
198           Mword dealign = (virt & 0x3) * 8;
199           *(Mword*)value = (*(Mword*)mem & (0xff << dealign)) >> dealign;
200         }
201         break;
202     case 2:
203         {
204           Mword dealign = ((virt & 0x2) >> 1) * 16;
205           *(Mword*)value = (*(Mword*)mem & (0xffff << dealign)) >> dealign;
206         }
207         break;
208     case 4:
209       memcpy(value, mem, width);
210     }
211
212   return 0;
213 }
214
215 PUBLIC static
216 int
217 Jdb::is_adapter_memory(Address, Space *)
218 {
219   return 0;
220 }
221
222 PUBLIC static
223 int
224 Jdb::poke_task(Address virt, Space * task, void const *val, int width)
225 {
226   void *mem = access_mem_task(virt, task);
227   if (!mem)
228     return -1;
229
230   memcpy(mem, val, width);
231   return 0;
232 }
233
234
235 PRIVATE static
236 void
237 Jdb::at_jdb_enter()
238 {
239   Mem_unit::clean_vdcache();
240 }
241
242 PRIVATE static
243 void
244 Jdb::at_jdb_leave()
245 {
246   Mem_unit::flush_vcache();
247 }
248
249 PUBLIC static inline
250 void
251 Jdb::enter_getchar()
252 {}
253
254 PUBLIC static inline
255 void
256 Jdb::leave_getchar()
257 {}
258
259 PUBLIC static
260 void
261 Jdb::write_tsc_s(Signed64 tsc, char *buf, int maxlen, bool sign)
262 {
263   if (sign)
264     {
265       *buf++ = (tsc < 0) ? '-' : (tsc == 0) ? ' ' : '+';
266       maxlen--;
267     }
268   snprintf(buf, maxlen, "%lld c", tsc);
269 }
270
271 PUBLIC static
272 void
273 Jdb::write_tsc(Signed64 tsc, char *buf, int maxlen, bool sign)
274 {
275   write_tsc_s(tsc, buf, maxlen, sign);
276 }
277
278 //----------------------------------------------------------------------------
279 IMPLEMENTATION [arm && !mp]:
280
281 PROTECTED static inline
282 template< typename T >
283 void
284 Jdb::set_monitored_address(T *dest, T val)
285 { *dest = val; }
286
287 //----------------------------------------------------------------------------
288 IMPLEMENTATION [arm && mp]:
289
290 #include <cstdio>
291
292 static
293 void
294 Jdb::send_nmi(unsigned cpu)
295 {
296   printf("NMI to %d, what's that?\n", cpu);
297 }
298
299 PROTECTED static inline
300 template< typename T >
301 void
302 Jdb::set_monitored_address(T *dest, T val)
303 {
304   *dest = val;
305   Mem::dsb();
306   asm volatile("sev");
307 }
308
309 PROTECTED static inline
310 template< typename T >
311 T Jdb::monitor_address(unsigned, T volatile *addr)
312 {
313   asm volatile("wfe");
314   return *addr;
315 }