This source file includes following definitions.
- get_sun4cpte
- get_sun4csegmap
- flush_cache_all_nop
- copy_ttentry
- eh_init
- exceptionHandler
- hex
- getpacket
- putpacket
- mem2hex
- hex2mem
- set_debug_traps
- computeSignal
- hexToInt
- handle_exception
- breakpoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 #include <linux/kernel.h>
98 #include <linux/string.h>
99 #include <linux/mm.h>
100
101 #include <asm/system.h>
102 #include <asm/signal.h>
103 #include <asm/oplib.h>
104 #include <asm/head.h>
105 #include <asm/traps.h>
106 #include <asm/system.h>
107 #include <asm/vac-ops.h>
108 #include <asm/kgdb.h>
109 #include <asm/pgtable.h>
110
111
112
113
114
115 extern void putDebugChar(char);
116 extern char getDebugChar(void);
117
118
119
120
121
122 #define BUFMAX 2048
123
124 static int initialized = 0;
125
126 static const char hexchars[]="0123456789abcdef";
127
128 #define NUMREGS 72
129
130
131 #define NUMREGBYTES (NUMREGS * 4)
132 enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
133 O0, O1, O2, O3, O4, O5, SP, O7,
134 L0, L1, L2, L3, L4, L5, L6, L7,
135 I0, I1, I2, I3, I4, I5, FP, I7,
136
137 F0, F1, F2, F3, F4, F5, F6, F7,
138 F8, F9, F10, F11, F12, F13, F14, F15,
139 F16, F17, F18, F19, F20, F21, F22, F23,
140 F24, F25, F26, F27, F28, F29, F30, F31,
141 Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
142
143
144 extern void trap_low(void);
145
146 unsigned long get_sun4cpte(unsigned long addr)
147 {
148 unsigned long entry;
149
150 __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" :
151 "=r" (entry) :
152 "r" (addr), "i" (ASI_PTE));
153 return entry;
154 }
155
156 unsigned long get_sun4csegmap(unsigned long addr)
157 {
158 unsigned long entry;
159
160 __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
161 "=r" (entry) :
162 "r" (addr), "i" (ASI_SEGMAP));
163 return entry;
164 }
165
166 static void flush_cache_all_nop(void)
167 {
168 }
169
170
171 struct tt_entry kgdb_savettable[256];
172 typedef void (*trapfunc_t)(void);
173
174
175 static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
176 {
177 dest->inst_one = src->inst_one;
178 dest->inst_two = src->inst_two;
179 dest->inst_three = src->inst_three;
180 dest->inst_four = src->inst_four;
181 }
182
183
184 static void eh_init(void)
185 {
186 int i, flags;
187
188 save_flags(flags); cli();
189 for(i=0; i < 256; i++)
190 copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
191 restore_flags(flags);
192 }
193
194
195 static void exceptionHandler(int tnum, trapfunc_t trap_entry)
196 {
197 unsigned long te_addr = (unsigned long) trap_entry;
198 int flags;
199
200
201 save_flags(flags); cli();
202
203
204 sparc_ttable[tnum].inst_one =
205 SPARC_BRANCH((unsigned long) te_addr,
206 (unsigned long) &sparc_ttable[tnum].inst_one);
207 sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
208 sparc_ttable[tnum].inst_three = SPARC_NOP;
209 sparc_ttable[tnum].inst_four = SPARC_NOP;
210
211 restore_flags(flags);
212 }
213
214
215 static int
216 hex(unsigned char ch)
217 {
218 if (ch >= 'a' && ch <= 'f')
219 return ch-'a'+10;
220 if (ch >= '0' && ch <= '9')
221 return ch-'0';
222 if (ch >= 'A' && ch <= 'F')
223 return ch-'A'+10;
224 return -1;
225 }
226
227
228 static void
229 getpacket(char *buffer)
230 {
231 unsigned char checksum;
232 unsigned char xmitcsum;
233 int i;
234 int count;
235 unsigned char ch;
236
237 do {
238
239 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
240
241 checksum = 0;
242 xmitcsum = -1;
243
244 count = 0;
245
246
247 while (count < BUFMAX) {
248 ch = getDebugChar() & 0x7f;
249 if (ch == '#')
250 break;
251 checksum = checksum + ch;
252 buffer[count] = ch;
253 count = count + 1;
254 }
255
256 if (count >= BUFMAX)
257 continue;
258
259 buffer[count] = 0;
260
261 if (ch == '#') {
262 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
263 xmitcsum |= hex(getDebugChar() & 0x7f);
264 if (checksum != xmitcsum)
265 putDebugChar('-');
266 else {
267 putDebugChar('+');
268
269 if (buffer[2] == ':') {
270 putDebugChar(buffer[0]);
271 putDebugChar(buffer[1]);
272
273 count = strlen(buffer);
274 for (i=3; i <= count; i++)
275 buffer[i-3] = buffer[i];
276 }
277 }
278 }
279 } while (checksum != xmitcsum);
280 }
281
282
283
284 static void
285 putpacket(unsigned char *buffer)
286 {
287 unsigned char checksum;
288 int count;
289 unsigned char ch, recv;
290
291
292 do {
293 putDebugChar('$');
294 checksum = 0;
295 count = 0;
296
297 while ((ch = buffer[count])) {
298 putDebugChar(ch);
299 checksum += ch;
300 count += 1;
301 }
302
303 putDebugChar('#');
304 putDebugChar(hexchars[checksum >> 4]);
305 putDebugChar(hexchars[checksum & 0xf]);
306 recv = getDebugChar();
307 } while ((recv & 0x7f) != '+');
308 }
309
310 static char remcomInBuffer[BUFMAX];
311 static char remcomOutBuffer[BUFMAX];
312
313
314
315
316
317
318 static unsigned char *
319 mem2hex(char *mem, char *buf, int count)
320 {
321 unsigned char ch;
322
323 while (count-- > 0) {
324 ch = *mem++;
325 *buf++ = hexchars[ch >> 4];
326 *buf++ = hexchars[ch & 0xf];
327 }
328
329 *buf = 0;
330 return buf;
331 }
332
333
334
335
336 static char *
337 hex2mem(char *buf, char *mem, int count)
338 {
339 int i;
340 unsigned char ch;
341
342 for (i=0; i<count; i++) {
343
344 ch = hex(*buf++) << 4;
345 ch |= hex(*buf++);
346 *mem++ = ch;
347 }
348 return mem;
349 }
350
351
352
353
354
355 static struct hard_trap_info
356 {
357 unsigned char tt;
358 unsigned char signo;
359 } hard_trap_info[] = {
360 {SP_TRAP_SBPT, SIGTRAP},
361 {0, 0}
362 };
363
364
365
366 void
367 set_debug_traps(void)
368 {
369 struct hard_trap_info *ht;
370 unsigned long flags;
371 unsigned char c;
372
373 save_flags(flags); cli();
374 flush_cache_all = flush_cache_all_nop;
375
376
377 eh_init();
378
379 for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
380
381 if((ht->tt != SP_TRAP_TFLT) &&
382 (ht->tt != SP_TRAP_DFLT))
383 exceptionHandler(ht->tt, trap_low);
384 }
385
386
387
388
389
390 while((c = getDebugChar()) != '$');
391 while((c = getDebugChar()) != '#');
392 c = getDebugChar();
393 c = getDebugChar();
394 putDebugChar('+');
395
396 initialized = 1;
397 restore_flags(flags);
398 }
399
400
401
402 static int
403 computeSignal(int tt)
404 {
405 struct hard_trap_info *ht;
406
407 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
408 if (ht->tt == tt)
409 return ht->signo;
410
411 return SIGHUP;
412 }
413
414
415
416
417
418
419 static int
420 hexToInt(char **ptr, int *intValue)
421 {
422 int numChars = 0;
423 int hexValue;
424
425 *intValue = 0;
426
427 while (**ptr) {
428 hexValue = hex(**ptr);
429 if (hexValue < 0)
430 break;
431
432 *intValue = (*intValue << 4) | hexValue;
433 numChars ++;
434
435 (*ptr)++;
436 }
437
438 return (numChars);
439 }
440
441
442
443
444
445
446
447 extern void breakinst(void);
448
449 void
450 handle_exception (unsigned long *registers)
451 {
452 int tt;
453 int sigval;
454 int addr;
455 int length;
456 char *ptr;
457 unsigned long *sp;
458
459
460
461 asm("save %sp, -64, %sp\n\t"
462 "save %sp, -64, %sp\n\t"
463 "save %sp, -64, %sp\n\t"
464 "save %sp, -64, %sp\n\t"
465 "save %sp, -64, %sp\n\t"
466 "save %sp, -64, %sp\n\t"
467 "save %sp, -64, %sp\n\t"
468 "save %sp, -64, %sp\n\t"
469 "restore\n\t"
470 "restore\n\t"
471 "restore\n\t"
472 "restore\n\t"
473 "restore\n\t"
474 "restore\n\t"
475 "restore\n\t"
476 "restore\n\t");
477
478 if (registers[PC] == (unsigned long)breakinst) {
479
480 registers[PC] = registers[NPC];
481 registers[NPC] += 4;
482 }
483
484 sp = (unsigned long *)registers[SP];
485
486 tt = (registers[TBR] >> 4) & 0xff;
487
488
489 sigval = computeSignal(tt);
490 ptr = remcomOutBuffer;
491
492 *ptr++ = 'T';
493 *ptr++ = hexchars[sigval >> 4];
494 *ptr++ = hexchars[sigval & 0xf];
495
496 *ptr++ = hexchars[PC >> 4];
497 *ptr++ = hexchars[PC & 0xf];
498 *ptr++ = ':';
499 ptr = mem2hex((char *)®isters[PC], ptr, 4);
500 *ptr++ = ';';
501
502 *ptr++ = hexchars[FP >> 4];
503 *ptr++ = hexchars[FP & 0xf];
504 *ptr++ = ':';
505 ptr = mem2hex((char *) (sp + 8 + 6), ptr, 4);
506 *ptr++ = ';';
507
508 *ptr++ = hexchars[SP >> 4];
509 *ptr++ = hexchars[SP & 0xf];
510 *ptr++ = ':';
511 ptr = mem2hex((char *)&sp, ptr, 4);
512 *ptr++ = ';';
513
514 *ptr++ = hexchars[NPC >> 4];
515 *ptr++ = hexchars[NPC & 0xf];
516 *ptr++ = ':';
517 ptr = mem2hex((char *)®isters[NPC], ptr, 4);
518 *ptr++ = ';';
519
520 *ptr++ = hexchars[O7 >> 4];
521 *ptr++ = hexchars[O7 & 0xf];
522 *ptr++ = ':';
523 ptr = mem2hex((char *)®isters[O7], ptr, 4);
524 *ptr++ = ';';
525
526 *ptr++ = 0;
527
528 putpacket(remcomOutBuffer);
529
530
531
532
533
534
535
536 while (1) {
537 remcomOutBuffer[0] = 0;
538
539 getpacket(remcomInBuffer);
540 switch (remcomInBuffer[0]) {
541 case '?':
542 remcomOutBuffer[0] = 'S';
543 remcomOutBuffer[1] = hexchars[sigval >> 4];
544 remcomOutBuffer[2] = hexchars[sigval & 0xf];
545 remcomOutBuffer[3] = 0;
546 break;
547
548 case 'd':
549
550 break;
551
552 case 'g':
553 {
554 ptr = remcomOutBuffer;
555
556 ptr = mem2hex((char *)registers, ptr, 16 * 4);
557
558 ptr = mem2hex((char *) (sp + 0), ptr, 16 * 4);
559
560 memset(ptr, '0', 32 * 8);
561
562 mem2hex((char *)®isters[Y], (ptr + 32 * 4 * 2), (8 * 4));
563 }
564 break;
565
566 case 'G':
567 {
568 unsigned long *newsp, psr;
569
570 psr = registers[PSR];
571
572 ptr = &remcomInBuffer[1];
573
574 hex2mem(ptr, (char *)registers, 16 * 4);
575
576 hex2mem(ptr + 16 * 4 * 2, (char *) (sp + 0), 16 * 4);
577
578 hex2mem(ptr + 64 * 4 * 2, (char *)®isters[Y], 8 * 4);
579
580
581
582
583
584
585
586 newsp = (unsigned long *)registers[SP];
587 if (sp != newsp)
588 sp = memcpy(newsp, sp, 16 * 4);
589
590
591
592 if (psr != registers[PSR])
593 registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
594
595 strcpy(remcomOutBuffer,"OK");
596 }
597 break;
598
599 case 'm':
600
601
602 ptr = &remcomInBuffer[1];
603
604 if (hexToInt(&ptr, &addr)
605 && *ptr++ == ','
606 && hexToInt(&ptr, &length)) {
607 if (mem2hex((char *)addr, remcomOutBuffer, length))
608 break;
609
610 strcpy (remcomOutBuffer, "E03");
611 } else {
612 strcpy(remcomOutBuffer,"E01");
613 }
614 break;
615
616 case 'M':
617
618
619 ptr = &remcomInBuffer[1];
620
621 if (hexToInt(&ptr, &addr)
622 && *ptr++ == ','
623 && hexToInt(&ptr, &length)
624 && *ptr++ == ':') {
625 if (hex2mem(ptr, (char *)addr, length)) {
626 strcpy(remcomOutBuffer, "OK");
627 } else {
628 strcpy(remcomOutBuffer, "E03");
629 }
630 } else {
631 strcpy(remcomOutBuffer, "E02");
632 }
633 break;
634
635 case 'c':
636
637
638 ptr = &remcomInBuffer[1];
639 if (hexToInt(&ptr, &addr)) {
640 registers[PC] = addr;
641 registers[NPC] = addr + 4;
642 }
643
644
645
646
647
648 flush_cache_all();
649 return;
650
651
652 case 'k' :
653 break;
654 case 'r':
655 asm ("call 0\n\t"
656 "nop\n\t");
657 break;
658 }
659
660
661 putpacket(remcomOutBuffer);
662 }
663 }
664
665
666
667
668
669
670 void
671 breakpoint(void)
672 {
673 if (!initialized)
674 return;
675
676
677 #ifndef __svr4__
678 asm(" .globl _breakinst
679
680 _breakinst: ta 1
681 ");
682 #else
683 asm(" .globl breakinst
684
685 breakinst: ta 1
686 ");
687 #endif
688 }