This source file includes following definitions.
- get_sun4cpte
- get_sun4csegmap
- 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
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
167 struct tt_entry kgdb_savettable[256];
168 typedef void (*trapfunc_t)(void);
169
170
171 static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
172 {
173 dest->inst_one = src->inst_one;
174 dest->inst_two = src->inst_two;
175 dest->inst_three = src->inst_three;
176 dest->inst_four = src->inst_four;
177 }
178
179
180 static void eh_init(void)
181 {
182 int i, flags;
183
184 save_flags(flags); cli();
185 for(i=0; i < 256; i++)
186 copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
187 restore_flags(flags);
188 }
189
190
191 static void exceptionHandler(int tnum, trapfunc_t trap_entry)
192 {
193 unsigned long te_addr = (unsigned long) trap_entry;
194 int flags;
195
196
197 save_flags(flags); cli();
198
199
200 sparc_ttable[tnum].inst_one =
201 SPARC_BRANCH((unsigned long) te_addr,
202 (unsigned long) &sparc_ttable[tnum].inst_one);
203 sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
204 sparc_ttable[tnum].inst_three = SPARC_NOP;
205 sparc_ttable[tnum].inst_four = SPARC_NOP;
206
207 restore_flags(flags);
208 }
209
210
211 static int
212 hex(unsigned char ch)
213 {
214 if (ch >= 'a' && ch <= 'f')
215 return ch-'a'+10;
216 if (ch >= '0' && ch <= '9')
217 return ch-'0';
218 if (ch >= 'A' && ch <= 'F')
219 return ch-'A'+10;
220 return -1;
221 }
222
223
224 static void
225 getpacket(char *buffer)
226 {
227 unsigned char checksum;
228 unsigned char xmitcsum;
229 int i;
230 int count;
231 unsigned char ch;
232
233 do {
234
235 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
236
237 checksum = 0;
238 xmitcsum = -1;
239
240 count = 0;
241
242
243 while (count < BUFMAX) {
244 ch = getDebugChar() & 0x7f;
245 if (ch == '#')
246 break;
247 checksum = checksum + ch;
248 buffer[count] = ch;
249 count = count + 1;
250 }
251
252 if (count >= BUFMAX)
253 continue;
254
255 buffer[count] = 0;
256
257 if (ch == '#') {
258 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
259 xmitcsum |= hex(getDebugChar() & 0x7f);
260 if (checksum != xmitcsum)
261 putDebugChar('-');
262 else {
263 putDebugChar('+');
264
265 if (buffer[2] == ':') {
266 putDebugChar(buffer[0]);
267 putDebugChar(buffer[1]);
268
269 count = strlen(buffer);
270 for (i=3; i <= count; i++)
271 buffer[i-3] = buffer[i];
272 }
273 }
274 }
275 } while (checksum != xmitcsum);
276 }
277
278
279
280 static void
281 putpacket(unsigned char *buffer)
282 {
283 unsigned char checksum;
284 int count;
285 unsigned char ch, recv;
286
287
288 do {
289 putDebugChar('$');
290 checksum = 0;
291 count = 0;
292
293 while ((ch = buffer[count])) {
294 putDebugChar(ch);
295 checksum += ch;
296 count += 1;
297 }
298
299 putDebugChar('#');
300 putDebugChar(hexchars[checksum >> 4]);
301 putDebugChar(hexchars[checksum & 0xf]);
302 recv = getDebugChar();
303 } while ((recv & 0x7f) != '+');
304 }
305
306 static char remcomInBuffer[BUFMAX];
307 static char remcomOutBuffer[BUFMAX];
308
309
310
311
312
313
314 static unsigned char *
315 mem2hex(char *mem, char *buf, int count)
316 {
317 unsigned char ch;
318
319 while (count-- > 0) {
320 ch = *mem++;
321 *buf++ = hexchars[ch >> 4];
322 *buf++ = hexchars[ch & 0xf];
323 }
324
325 *buf = 0;
326 return buf;
327 }
328
329
330
331
332 static char *
333 hex2mem(char *buf, char *mem, int count)
334 {
335 int i;
336 unsigned char ch;
337
338 for (i=0; i<count; i++) {
339
340 ch = hex(*buf++) << 4;
341 ch |= hex(*buf++);
342 *mem++ = ch;
343 }
344 return mem;
345 }
346
347
348
349
350
351 static struct hard_trap_info
352 {
353 unsigned char tt;
354 unsigned char signo;
355 } hard_trap_info[] = {
356 {SP_TRAP_SBPT, SIGTRAP},
357 {0, 0}
358 };
359
360
361
362 void
363 set_debug_traps(void)
364 {
365 struct hard_trap_info *ht;
366 unsigned char c;
367
368
369 eh_init();
370
371 for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
372
373 if((ht->tt != SP_TRAP_TFLT) &&
374 (ht->tt != SP_TRAP_DFLT))
375 exceptionHandler(ht->tt, trap_low);
376 }
377
378
379
380
381
382 while((c = getDebugChar()) != '$');
383 while((c = getDebugChar()) != '#');
384 c = getDebugChar();
385 c = getDebugChar();
386 putDebugChar('+');
387
388 initialized = 1;
389 }
390
391
392
393 static int
394 computeSignal(int tt)
395 {
396 struct hard_trap_info *ht;
397
398 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
399 if (ht->tt == tt)
400 return ht->signo;
401
402 return SIGHUP;
403 }
404
405
406
407
408
409
410 static int
411 hexToInt(char **ptr, int *intValue)
412 {
413 int numChars = 0;
414 int hexValue;
415
416 *intValue = 0;
417
418 while (**ptr) {
419 hexValue = hex(**ptr);
420 if (hexValue < 0)
421 break;
422
423 *intValue = (*intValue << 4) | hexValue;
424 numChars ++;
425
426 (*ptr)++;
427 }
428
429 return (numChars);
430 }
431
432
433
434
435
436
437
438 extern void breakinst(void);
439
440 void
441 handle_exception (unsigned long *registers)
442 {
443 int tt;
444 int sigval;
445 int addr;
446 int length;
447 char *ptr;
448 unsigned long *sp;
449
450
451
452 asm("save %sp, -64, %sp\n\t"
453 "save %sp, -64, %sp\n\t"
454 "save %sp, -64, %sp\n\t"
455 "save %sp, -64, %sp\n\t"
456 "save %sp, -64, %sp\n\t"
457 "save %sp, -64, %sp\n\t"
458 "save %sp, -64, %sp\n\t"
459 "save %sp, -64, %sp\n\t"
460 "restore\n\t"
461 "restore\n\t"
462 "restore\n\t"
463 "restore\n\t"
464 "restore\n\t"
465 "restore\n\t"
466 "restore\n\t"
467 "restore\n\t");
468
469 if (registers[PC] == (unsigned long)breakinst) {
470
471 registers[PC] = registers[NPC];
472 registers[NPC] += 4;
473 }
474
475 sp = (unsigned long *)registers[SP];
476
477 tt = (registers[TBR] >> 4) & 0xff;
478
479
480 sigval = computeSignal(tt);
481 ptr = remcomOutBuffer;
482
483 *ptr++ = 'T';
484 *ptr++ = hexchars[sigval >> 4];
485 *ptr++ = hexchars[sigval & 0xf];
486
487 *ptr++ = hexchars[PC >> 4];
488 *ptr++ = hexchars[PC & 0xf];
489 *ptr++ = ':';
490 ptr = mem2hex((char *)®isters[PC], ptr, 4);
491 *ptr++ = ';';
492
493 *ptr++ = hexchars[FP >> 4];
494 *ptr++ = hexchars[FP & 0xf];
495 *ptr++ = ':';
496 ptr = mem2hex((char *) (sp + 8 + 6), ptr, 4);
497 *ptr++ = ';';
498
499 *ptr++ = hexchars[SP >> 4];
500 *ptr++ = hexchars[SP & 0xf];
501 *ptr++ = ':';
502 ptr = mem2hex((char *)&sp, ptr, 4);
503 *ptr++ = ';';
504
505 *ptr++ = hexchars[NPC >> 4];
506 *ptr++ = hexchars[NPC & 0xf];
507 *ptr++ = ':';
508 ptr = mem2hex((char *)®isters[NPC], ptr, 4);
509 *ptr++ = ';';
510
511 *ptr++ = hexchars[O7 >> 4];
512 *ptr++ = hexchars[O7 & 0xf];
513 *ptr++ = ':';
514 ptr = mem2hex((char *)®isters[O7], ptr, 4);
515 *ptr++ = ';';
516
517 *ptr++ = 0;
518
519 putpacket(remcomOutBuffer);
520
521
522
523
524
525
526
527 while (1) {
528 remcomOutBuffer[0] = 0;
529
530 getpacket(remcomInBuffer);
531 switch (remcomInBuffer[0]) {
532 case '?':
533 remcomOutBuffer[0] = 'S';
534 remcomOutBuffer[1] = hexchars[sigval >> 4];
535 remcomOutBuffer[2] = hexchars[sigval & 0xf];
536 remcomOutBuffer[3] = 0;
537 break;
538
539 case 'd':
540
541 break;
542
543 case 'g':
544 {
545 ptr = remcomOutBuffer;
546
547 ptr = mem2hex((char *)registers, ptr, 16 * 4);
548
549 ptr = mem2hex((char *) (sp + 0), ptr, 16 * 4);
550
551 memset(ptr, '0', 32 * 8);
552
553 mem2hex((char *)®isters[Y], (ptr + 32 * 4 * 2), (8 * 4));
554 }
555 break;
556
557 case 'G':
558 {
559 unsigned long *newsp, psr;
560
561 psr = registers[PSR];
562
563 ptr = &remcomInBuffer[1];
564
565 hex2mem(ptr, (char *)registers, 16 * 4);
566
567 hex2mem(ptr + 16 * 4 * 2, (char *) (sp + 0), 16 * 4);
568
569 hex2mem(ptr + 64 * 4 * 2, (char *)®isters[Y], 8 * 4);
570
571
572
573
574
575
576
577 newsp = (unsigned long *)registers[SP];
578 if (sp != newsp)
579 sp = memcpy(newsp, sp, 16 * 4);
580
581
582
583 if (psr != registers[PSR])
584 registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
585
586 strcpy(remcomOutBuffer,"OK");
587 }
588 break;
589
590 case 'm':
591
592
593 ptr = &remcomInBuffer[1];
594
595 if (hexToInt(&ptr, &addr)
596 && *ptr++ == ','
597 && hexToInt(&ptr, &length)) {
598 if (mem2hex((char *)addr, remcomOutBuffer, length))
599 break;
600
601 strcpy (remcomOutBuffer, "E03");
602 } else {
603 strcpy(remcomOutBuffer,"E01");
604 }
605 break;
606
607 case 'M':
608
609
610 ptr = &remcomInBuffer[1];
611
612 if (hexToInt(&ptr, &addr)
613 && *ptr++ == ','
614 && hexToInt(&ptr, &length)
615 && *ptr++ == ':') {
616 if (hex2mem(ptr, (char *)addr, length)) {
617 strcpy(remcomOutBuffer, "OK");
618 } else {
619 strcpy(remcomOutBuffer, "E03");
620 }
621 } else {
622 strcpy(remcomOutBuffer, "E02");
623 }
624 break;
625
626 case 'c':
627
628
629 ptr = &remcomInBuffer[1];
630 if (hexToInt(&ptr, &addr)) {
631 registers[PC] = addr;
632 registers[NPC] = addr + 4;
633 }
634
635
636
637
638
639
640
641
642
643
644 if((sparc_cpu_model==sun4 || sparc_cpu_model==sun4c) &&
645 (sun4c_vacinfo.num_bytes && sun4c_vacinfo.on))
646 sun4c_flush_context();
647
648
649
650
651 return;
652
653
654 case 'k' :
655 break;
656 case 'r':
657 asm ("call 0\n\t"
658 "nop\n\t");
659 break;
660 }
661
662
663 putpacket(remcomOutBuffer);
664 }
665 }
666
667
668
669
670
671
672 void
673 breakpoint(void)
674 {
675 if (!initialized)
676 return;
677
678
679 #ifndef __svr4__
680 asm(" .globl _breakinst
681
682 _breakinst: ta 1
683 ");
684 #else
685 asm(" .globl breakinst
686
687 breakinst: ta 1
688 ");
689 #endif
690 }