root/arch/mips/kernel/gdb-stub.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hex
  2. getpacket
  3. putpacket
  4. mem2hex
  5. hex2mem
  6. set_debug_traps
  7. fltr_set_mem_err
  8. set_mem_fault_trap
  9. computeSignal
  10. hexToInt
  11. handle_exception
  12. breakpoint
  13. adel
  14. show_gdbregs

   1 /*
   2  *  arch/mips/kernel/gdb-stub.c
   3  *
   4  *  Originally written by Glenn Engel, Lake Stevens Instrument Division
   5  *
   6  *  Contributed by HP Systems
   7  *
   8  *  Modified for SPARC by Stu Grossman, Cygnus Support.
   9  *
  10  *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
  11  *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
  12  *
  13  *  Copyright (C) 1995 Andreas Busse
  14  */
  15 
  16 /*
  17  *  To enable debugger support, two things need to happen.  One, a
  18  *  call to set_debug_traps() is necessary in order to allow any breakpoints
  19  *  or error conditions to be properly intercepted and reported to gdb.
  20  *  Two, a breakpoint needs to be generated to begin communication.  This
  21  *  is most easily accomplished by a call to breakpoint().  Breakpoint()
  22  *  simulates a breakpoint by executing a BREAK instruction.
  23  *
  24  *
  25  *    The following gdb commands are supported:
  26  *
  27  * command          function                               Return value
  28  *
  29  *    g             return the value of the CPU registers  hex data or ENN
  30  *    G             set the value of the CPU registers     OK or ENN
  31  *
  32  *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
  33  *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
  34  *
  35  *    c             Resume at current address              SNN   ( signal NN)
  36  *    cAA..AA       Continue at address AA..AA             SNN
  37  *
  38  *    s             Step one instruction                   SNN
  39  *    sAA..AA       Step one instruction from AA..AA       SNN
  40  *
  41  *    k             kill
  42  *
  43  *    ?             What was the last sigval ?             SNN   (signal NN)
  44  *
  45  *    bBB..BB       Set baud rate to BB..BB                OK or BNN, then sets
  46  *                                                         baud rate
  47  *
  48  * All commands and responses are sent with a packet which includes a
  49  * checksum.  A packet consists of
  50  *
  51  * $<packet info>#<checksum>.
  52  *
  53  * where
  54  * <packet info> :: <characters representing the command or response>
  55  * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
  56  *
  57  * When a packet is received, it is first acknowledged with either '+' or '-'.
  58  * '+' indicates a successful transfer.  '-' indicates a failed transfer.
  59  *
  60  * Example:
  61  *
  62  * Host:                  Reply:
  63  * $m0,10#2a               +$00010203040506070809101112131415#42
  64  *
  65  */
  66 
  67 #include <linux/string.h>
  68 #include <linux/signal.h>
  69 #include <linux/kernel.h>
  70 
  71 #include <asm/asm.h>
  72 #include <asm/mipsregs.h>
  73 #include <asm/segment.h>
  74 #include <asm/cachectl.h>
  75 #include <asm/system.h>
  76 #include <asm/gdb-stub.h>
  77 
  78 /*
  79  * external low-level support routines
  80  */
  81 
  82 extern int putDebugChar(char c);    /* write a single character      */
  83 extern char getDebugChar(void);     /* read and return a single char */
  84 extern void fltr_set_mem_err(void);
  85 extern void trap_low(void);
  86 
  87 /*
  88  * breakpoint and test functions
  89  */
  90 extern void breakpoint(void);
  91 extern void breakinst(void);
  92 extern void adel(void);
  93 
  94 /*
  95  * local prototypes
  96  */
  97 
  98 static void getpacket(char *buffer);
  99 static void putpacket(char *buffer);
 100 static void set_mem_fault_trap(int enable);
 101 static int computeSignal(int tt);
 102 static int hex(unsigned char ch);
 103 static int hexToInt(char **ptr, int *intValue);
 104 static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);
 105 void handle_exception(struct gdb_regs *regs);
 106 static void show_gdbregs(struct gdb_regs *regs);
 107 
 108 /*
 109  * BUFMAX defines the maximum number of characters in inbound/outbound buffers
 110  * at least NUMREGBYTES*2 are needed for register packets
 111  */
 112 #define BUFMAX 2048
 113 
 114 static char input_buffer[BUFMAX];
 115 static char output_buffer[BUFMAX];
 116 static int initialized = 0;     /* !0 means we've been initialized */
 117 static const char hexchars[]="0123456789abcdef";
 118 
 119 
 120 /*
 121  * Convert ch from a hex digit to an int
 122  */
 123 static int hex(unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         if (ch >= 'a' && ch <= 'f')
 126                 return ch-'a'+10;
 127         if (ch >= '0' && ch <= '9')
 128                 return ch-'0';
 129         if (ch >= 'A' && ch <= 'F')
 130                 return ch-'A'+10;
 131         return -1;
 132 }
 133 
 134 /*
 135  * scan for the sequence $<data>#<checksum>
 136  */
 137 static void getpacket(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139         unsigned char checksum;
 140         unsigned char xmitcsum;
 141         int i;
 142         int count;
 143         unsigned char ch;
 144 
 145         do {
 146                 /*
 147                  * wait around for the start character,
 148                  * ignore all other characters
 149                  */
 150                 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
 151 
 152                 checksum = 0;
 153                 xmitcsum = -1;
 154                 count = 0;
 155         
 156                 /*
 157                  * now, read until a # or end of buffer is found
 158                  */
 159                 while (count < BUFMAX) {
 160                         ch = getDebugChar() & 0x7f;
 161                         if (ch == '#')
 162                                 break;
 163                         checksum = checksum + ch;
 164                         buffer[count] = ch;
 165                         count = count + 1;
 166                 }
 167 
 168                 if (count >= BUFMAX)
 169                         continue;
 170 
 171                 buffer[count] = 0;
 172 
 173                 if (ch == '#') {
 174                         xmitcsum = hex(getDebugChar() & 0x7f) << 4;
 175                         xmitcsum |= hex(getDebugChar() & 0x7f);
 176 
 177                         if (checksum != xmitcsum)
 178                                 putDebugChar('-');      /* failed checksum */
 179                         else {
 180                                 putDebugChar('+'); /* successful transfer */
 181 
 182                                 /*
 183                                  * if a sequence char is present,
 184                                  * reply the sequence ID
 185                                  */
 186                                 if (buffer[2] == ':') {
 187                                         putDebugChar(buffer[0]);
 188                                         putDebugChar(buffer[1]);
 189 
 190                                         /*
 191                                          * remove sequence chars from buffer
 192                                          */
 193                                         count = strlen(buffer);
 194                                         for (i=3; i <= count; i++)
 195                                                 buffer[i-3] = buffer[i];
 196                                 }
 197                         }
 198                 }
 199         }
 200         while (checksum != xmitcsum);
 201 }
 202 
 203 /*
 204  * send the packet in buffer.
 205  */
 206 static void putpacket(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         unsigned char checksum;
 209         int count;
 210         unsigned char ch;
 211 
 212         /*
 213          * $<packet info>#<checksum>.
 214          */
 215 
 216         do {
 217                 putDebugChar('$');
 218                 checksum = 0;
 219                 count = 0;
 220 
 221                 while ((ch = buffer[count]) != 0) {
 222                         if (!(putDebugChar(ch)))
 223                                 return;
 224                         checksum += ch;
 225                         count += 1;
 226                 }
 227 
 228                 putDebugChar('#');
 229                 putDebugChar(hexchars[checksum >> 4]);
 230                 putDebugChar(hexchars[checksum & 0xf]);
 231 
 232         }
 233         while ((getDebugChar() & 0x7f) != '+');
 234 }
 235 
 236 
 237 /*
 238  * Indicate to caller of mem2hex or hex2mem that there
 239  * has been an error.
 240  */
 241 static volatile int mem_err = 0;
 242 
 243 /*
 244  * Convert the memory pointed to by mem into hex, placing result in buf.
 245  * Return a pointer to the last char put in buf (null), in case of mem fault,
 246  * return 0.
 247  * If MAY_FAULT is non-zero, then we will handle memory faults by returning
 248  * a 0, else treat a fault like any other fault in the stub.
 249  */
 250 static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252         unsigned char ch;
 253 
 254 /*      set_mem_fault_trap(may_fault); */
 255 
 256         while (count-- > 0) {
 257                 ch = *(mem++);
 258                 if (mem_err)
 259                         return 0;
 260                 *buf++ = hexchars[ch >> 4];
 261                 *buf++ = hexchars[ch & 0xf];
 262         }
 263 
 264         *buf = 0;
 265 
 266 /*      set_mem_fault_trap(0); */
 267 
 268         return buf;
 269 }
 270 
 271 /*
 272  * convert the hex array pointed to by buf into binary to be placed in mem
 273  * return a pointer to the character AFTER the last byte written
 274  */
 275 static char *hex2mem(char *buf, char *mem, int count, int may_fault)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         int i;
 278         unsigned char ch;
 279 
 280 /*      set_mem_fault_trap(may_fault); */
 281 
 282         for (i=0; i<count; i++)
 283         {
 284                 ch = hex(*buf++) << 4;
 285                 ch |= hex(*buf++);
 286                 *(mem++) = ch;
 287                 if (mem_err)
 288                         return 0;
 289         }
 290 
 291 /*      set_mem_fault_trap(0); */
 292 
 293         return mem;
 294 }
 295 
 296 /*
 297  * This table contains the mapping between SPARC hardware trap types, and
 298  * signals, which are primarily what GDB understands.  It also indicates
 299  * which hardware traps we need to commandeer when initializing the stub.
 300  */
 301 static struct hard_trap_info
 302 {
 303         unsigned char tt;               /* Trap type code for MIPS R3xxx and R4xxx */
 304         unsigned char signo;            /* Signal that we map this trap into */
 305 } hard_trap_info[] = {
 306         { 4, SIGBUS },                  /* address error (load) */
 307         { 5, SIGBUS },                  /* address error (store) */
 308         { 6, SIGBUS },                  /* instruction bus error */
 309         { 7, SIGBUS },                  /* data bus error */
 310         { 9, SIGTRAP },                 /* break */
 311         { 10, SIGILL },                 /* reserved instruction */
 312 /*      { 11, SIGILL },         */      /* cpu unusable */
 313         { 12, SIGFPE },                 /* overflow */
 314         { 13, SIGTRAP },                /* trap */
 315         { 14, SIGSEGV },                /* virtual instruction cache coherency */
 316         { 15, SIGFPE },                 /* floating point exception */
 317         { 23, SIGSEGV },                /* watch */
 318         { 31, SIGSEGV },                /* virtual data cache coherency */
 319         { 0, 0}                         /* Must be last */
 320 };
 321 
 322 
 323 /*
 324  * Set up exception handlers for tracing and breakpoints
 325  */
 326 void set_debug_traps(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328         struct hard_trap_info *ht;
 329 
 330         for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
 331                 set_except_vector(ht->tt, trap_low);
 332   
 333         /*
 334          * In case GDB is started before us, ack any packets
 335          * (presumably "$?#xx") sitting there.
 336          */
 337 
 338         putDebugChar ('+');
 339         initialized = 1;
 340 
 341         breakpoint();
 342 }
 343 
 344 
 345 /*
 346  * Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
 347  * assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
 348  * 0 would ever contain code that could mem fault.  This routine will skip
 349  * past the faulting instruction after setting mem_err.
 350  */
 351 extern void fltr_set_mem_err(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 352 {
 353   /* FIXME: Needs to be written... */
 354 }
 355 
 356 
 357 static void set_mem_fault_trap(int enable)
     /* [previous][next][first][last][top][bottom][index][help] */
 358 {
 359   mem_err = 0;
 360 
 361 #if 0
 362   if (enable)
 363     exceptionHandler(9, fltr_set_mem_err);
 364   else
 365     exceptionHandler(9, trap_low);
 366 #endif  
 367 }
 368 
 369 /*
 370  * Convert the MIPS hardware trap type code to a unix signal number.
 371  */
 372 static int computeSignal(int tt)
     /* [previous][next][first][last][top][bottom][index][help] */
 373 {
 374         struct hard_trap_info *ht;
 375 
 376         for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
 377                 if (ht->tt == tt)
 378                         return ht->signo;
 379 
 380         return SIGHUP;          /* default for things we don't know about */
 381 }
 382 
 383 /*
 384  * While we find nice hex chars, build an int.
 385  * Return number of chars processed.
 386  */
 387 static int hexToInt(char **ptr, int *intValue)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389         int numChars = 0;
 390         int hexValue;
 391 
 392         *intValue = 0;
 393 
 394         while (**ptr)
 395         {
 396                 hexValue = hex(**ptr);
 397                 if (hexValue < 0)
 398                         break;
 399 
 400                 *intValue = (*intValue << 4) | hexValue;
 401                 numChars ++;
 402 
 403                 (*ptr)++;
 404         }
 405 
 406         return (numChars);
 407 }
 408 
 409 /*
 410  * This function does all command procesing for interfacing to gdb.  It
 411  * returns 1 if you should skip the instruction at the trap address, 0
 412  * otherwise.
 413  */
 414 void handle_exception (struct gdb_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 415 {
 416         int trap;                       /* Trap type */
 417         int sigval;
 418         int addr;
 419         int length;
 420         char *ptr;
 421         unsigned long *stack;
 422 
 423 #if 0   
 424         printk("in handle_exception()\n");
 425         show_gdbregs(regs);
 426 #endif
 427         
 428         /*
 429          * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1,
 430          * the simply switch the FPU on and return since this is no error
 431          * condition. kernel/traps.c does the same.
 432          * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE
 433          * traps for now.
 434          */
 435         trap = (regs->cp0_cause & 0x7c) >> 2;
 436 /*      printk("trap=%d\n",trap); */
 437         if (trap == 11) {
 438                 if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) {
 439                         regs->cp0_status |= ST0_CU1;
 440                         return;
 441                 }
 442         }
 443 
 444         /*
 445          * If we're in breakpoint() increment the PC
 446          */
 447         if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)             
 448                 regs->cp0_epc += 4;
 449 
 450         stack = (long *)regs->reg29;                    /* stack ptr */
 451         sigval = computeSignal(trap);
 452 
 453         /*
 454          * reply to host that an exception has occurred
 455          */
 456         ptr = output_buffer;
 457 
 458         /*
 459          * Send trap type (converted to signal)
 460          */
 461         *ptr++ = 'T';
 462         *ptr++ = hexchars[sigval >> 4];
 463         *ptr++ = hexchars[sigval & 0xf];
 464 
 465         /*
 466          * Send Error PC
 467          */
 468         *ptr++ = hexchars[REG_EPC >> 4];
 469         *ptr++ = hexchars[REG_EPC & 0xf];
 470         *ptr++ = ':';
 471         ptr = mem2hex((char *)&regs->cp0_epc, ptr, 4, 0);
 472         *ptr++ = ';';
 473 
 474         /*
 475          * Send frame pointer
 476          */
 477         *ptr++ = hexchars[REG_FP >> 4];
 478         *ptr++ = hexchars[REG_FP & 0xf];
 479         *ptr++ = ':';
 480         ptr = mem2hex((char *)&regs->reg30, ptr, 4, 0);
 481         *ptr++ = ';';
 482 
 483         /*
 484          * Send stack pointer
 485          */
 486         *ptr++ = hexchars[REG_SP >> 4];
 487         *ptr++ = hexchars[REG_SP & 0xf];
 488         *ptr++ = ':';
 489         ptr = mem2hex((char *)&regs->reg29, ptr, 4, 0);
 490         *ptr++ = ';';
 491 
 492         *ptr++ = 0;
 493         putpacket(output_buffer);       /* send it off... */
 494 
 495         /*
 496          * Wait for input from remote GDB
 497          */
 498         while (1) {
 499                 output_buffer[0] = 0;
 500                 getpacket(input_buffer);
 501 
 502                 switch (input_buffer[0])
 503                 {
 504                 case '?':
 505                         output_buffer[0] = 'S';
 506                         output_buffer[1] = hexchars[sigval >> 4];
 507                         output_buffer[2] = hexchars[sigval & 0xf];
 508                         output_buffer[3] = 0;
 509                         break;
 510 
 511                 case 'd':
 512                         /* toggle debug flag */
 513                         break;
 514 
 515                 /*
 516                  * Return the value of the CPU registers
 517                  */
 518                 case 'g':
 519                         ptr = output_buffer;
 520                         ptr = mem2hex((char *)&regs->reg0, ptr, 32*4, 0); /* r0...r31 */
 521                         ptr = mem2hex((char *)&regs->cp0_status, ptr, 6*4, 0); /* cp0 */
 522                         ptr = mem2hex((char *)&regs->fpr0, ptr, 32*4, 0); /* f0...31 */
 523                         ptr = mem2hex((char *)&regs->cp1_fsr, ptr, 2*4, 0); /* cp1 */
 524                         ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*4, 0); /* frp */
 525                         ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*4, 0); /* cp0 */
 526                         break;
 527           
 528                 /*
 529                  * set the value of the CPU registers - return OK
 530                  * FIXME: Needs to be written
 531                  */
 532                 case 'G':
 533                 {
 534 #if 0
 535                         unsigned long *newsp, psr;
 536 
 537                         ptr = &input_buffer[1];
 538                         hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
 539 
 540                         /*
 541                          * See if the stack pointer has moved. If so, then copy the
 542                          * saved locals and ins to the new location.
 543                          */
 544 
 545                         newsp = (unsigned long *)registers[SP];
 546                         if (sp != newsp)
 547                                 sp = memcpy(newsp, sp, 16 * 4);
 548 
 549 #endif
 550                         strcpy(output_buffer,"OK");
 551                  }
 552                 break;
 553 
 554                 /*
 555                  * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
 556                  */
 557                 case 'm':
 558                         ptr = &input_buffer[1];
 559 
 560                         if (hexToInt(&ptr, &addr)
 561                                 && *ptr++ == ','
 562                                 && hexToInt(&ptr, &length)) {
 563                                 if (mem2hex((char *)addr, output_buffer, length, 1))
 564                                         break;
 565                                 strcpy (output_buffer, "E03");
 566                         } else
 567                                 strcpy(output_buffer,"E01");
 568                         break;
 569 
 570                 /*
 571                  * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
 572                  */
 573                 case 'M': 
 574                         ptr = &input_buffer[1];
 575 
 576                         if (hexToInt(&ptr, &addr)
 577                                 && *ptr++ == ','
 578                                 && hexToInt(&ptr, &length)
 579                                 && *ptr++ == ':') {
 580                                 if (hex2mem(ptr, (char *)addr, length, 1))
 581                                         strcpy(output_buffer, "OK");
 582                                 else
 583                                         strcpy(output_buffer, "E03");
 584                         }
 585                         else
 586                                 strcpy(output_buffer, "E02");
 587                         break;
 588 
 589                 /*
 590                  * cAA..AA    Continue at address AA..AA(optional)
 591                  */
 592                 case 'c':    
 593                         /* try to read optional parameter, pc unchanged if no parm */
 594 
 595                         ptr = &input_buffer[1];
 596                         if (hexToInt(&ptr, &addr))
 597                                 regs->cp0_epc = addr;
 598           
 599                         /*
 600                          * Need to flush the instruction cache here, as we may
 601                          * have deposited a breakpoint, and the icache probably
 602                          * has no way of knowing that a data ref to some location
 603                          * may have changed something that is in the instruction
 604                          * cache.
 605                          * NB: We flush both caches, just to be sure...
 606                          */
 607 
 608                         sys_cacheflush((void *)KSEG0,KSEG1-KSEG0,BCACHE);
 609                         return;
 610                         /* NOTREACHED */
 611                         break;
 612 
 613 
 614                 /*
 615                  * kill the program
 616                  */
 617                 case 'k' :
 618                         break;          /* do nothing */
 619 
 620 
 621                 /*
 622                  * Reset the whole machine (FIXME: system dependent)
 623                  */
 624                 case 'r':
 625                         break;
 626 
 627 
 628                 /*
 629                  * Step to next instruction
 630                  * FIXME: Needs to be written
 631                  */
 632                 case 's':
 633                         strcpy (output_buffer, "S01");
 634                         break;
 635 
 636                 /*
 637                  * Set baud rate (bBB)
 638                  * FIXME: Needs to be written
 639                  */
 640                 case 'b':
 641                 {
 642 #if 0                           
 643                         int baudrate;
 644                         extern void set_timer_3();
 645 
 646                         ptr = &input_buffer[1];
 647                         if (!hexToInt(&ptr, &baudrate))
 648                         {
 649                                 strcpy(output_buffer,"B01");
 650                                 break;
 651                         }
 652 
 653                         /* Convert baud rate to uart clock divider */
 654 
 655                         switch (baudrate)
 656                         {
 657                                 case 38400:
 658                                         baudrate = 16;
 659                                         break;
 660                                 case 19200:
 661                                         baudrate = 33;
 662                                         break;
 663                                 case 9600:
 664                                         baudrate = 65;
 665                                         break;
 666                                 default:
 667                                         baudrate = 0;
 668                                         strcpy(output_buffer,"B02");
 669                                         goto x1;
 670                         }
 671 
 672                         if (baudrate) {
 673                                 putpacket("OK");        /* Ack before changing speed */
 674                                 set_timer_3(baudrate); /* Set it */
 675                         }
 676 #endif
 677                 }
 678                 break;
 679 
 680                 }                       /* switch */
 681 
 682                 /*
 683                  * reply to the request
 684                  */
 685 
 686                 putpacket(output_buffer);
 687 
 688         } /* while */
 689 }
 690 
 691 /*
 692  * This function will generate a breakpoint exception.  It is used at the
 693  * beginning of a program to sync up with a debugger and can be used
 694  * otherwise as a quick means to stop program execution and "break" into
 695  * the debugger.
 696  */
 697 void breakpoint(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 698 {
 699         if (!initialized)
 700                 return;
 701 
 702         __asm__ __volatile__("
 703                         .globl  breakinst
 704                         .set    noreorder
 705                         nop
 706 breakinst:              break
 707                         nop
 708                         .set    reorder
 709         ");
 710 }
 711 
 712 void adel(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 713 {
 714         __asm__ __volatile__("
 715                         .globl  adel
 716                         la      $8,0x80000001
 717                         lw      $9,0($8)
 718         ");
 719 }
 720 
 721 /*
 722  * Print registers (on target console)
 723  * Used only to debug the stub...
 724  */
 725 void show_gdbregs(struct gdb_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 726 {
 727         /*
 728          * Saved main processor registers
 729          */
 730         printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 731                regs->reg0, regs->reg1, regs->reg2, regs->reg3,
 732                regs->reg4, regs->reg5, regs->reg6, regs->reg7);
 733         printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 734                regs->reg8, regs->reg9, regs->reg10, regs->reg11,
 735                regs->reg12, regs->reg13, regs->reg14, regs->reg15);
 736         printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 737                regs->reg16, regs->reg17, regs->reg18, regs->reg19,
 738                regs->reg20, regs->reg21, regs->reg22, regs->reg23);
 739         printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
 740                regs->reg24, regs->reg25, regs->reg26, regs->reg27,
 741                regs->reg28, regs->reg29, regs->reg30, regs->reg31);
 742 
 743         /*
 744          * Saved cp0 registers
 745          */
 746         printk("epc  : %08lx\nStatus: %08lx\nCause : %08lx\n",
 747                regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
 748 }

/* [previous][next][first][last][top][bottom][index][help] */