xtensa-cvscommit Mailing List for xtensa (Page 10)
Brought to you by:
zankel
You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(18) |
Oct
(30) |
Nov
(18) |
Dec
(12) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(24) |
Feb
(38) |
Mar
(28) |
Apr
(27) |
May
(17) |
Jun
(6) |
Jul
(12) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
| 2004 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <sfo...@us...> - 2002-09-22 21:18:06
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv28463
Modified Files:
gdb-stub.c handlers.S
Log Message:
Support for reading "ar" registers via kgdb, besides the ones mapped by registers a0-15.
General cleanup of gdb-stub.c
Index: gdb-stub.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/gdb-stub.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** gdb-stub.c 19 Sep 2002 07:06:11 -0000 1.2
--- gdb-stub.c 22 Sep 2002 21:18:02 -0000 1.3
***************
*** 99,103 ****
static void getpacket(char *buffer);
static void putpacket(char *buffer);
- static int computeSignal(int tt);
static int hex(unsigned char ch);
static int hexToInt(char **ptr, int *intValue);
--- 99,102 ----
***************
*** 121,126 ****
/* saved_ar_regs provide a buffer to save the ar registers on debug
! * exceptions. */
! int saved_ar_regs[XCHAL_NUM_AREGS];
/* return_from_debug_flag is used to signal the exception handler to restore
* the ar registers from saved_ar_regs on return. */
--- 120,125 ----
/* saved_ar_regs provide a buffer to save the ar registers on debug
! * exceptions. Save all ar regs, plus wb and ws on top. */
! int saved_ar_regs[XCHAL_NUM_AREGS + 2];
/* return_from_debug_flag is used to signal the exception handler to restore
* the ar registers from saved_ar_regs on return. */
***************
*** 312,338 ****
}
- /*
- * This table contains the mapping between SPARC hardware trap types, and
- * signals, which are primarily what GDB understands. It also indicates
- * which hardware traps we need to commandeer when initializing the stub.
- */
- static struct hard_trap_info {
- unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
- unsigned char signo; /* Signal that we map this trap into */
- } hard_trap_info[] = {
- { 6, SIGBUS }, /* instruction bus error */
- { 7, SIGBUS }, /* data bus error */
- { 9, SIGTRAP }, /* break */
- { 10, SIGILL }, /* reserved instruction */
- /* { 11, SIGILL }, */ /* CPU unusable */
- { 12, SIGFPE }, /* overflow */
- { 13, SIGTRAP }, /* trap */
- { 14, SIGSEGV }, /* virtual instruction cache coherency */
- { 15, SIGFPE }, /* floating point exception */
- { 23, SIGSEGV }, /* watch */
- { 31, SIGSEGV }, /* virtual data cache coherency */
- { 0, 0} /* Must be last */
- };
-
/*
--- 311,314 ----
***************
*** 345,349 ****
{
unsigned long flags;
- unsigned char c;
#if 0
--- 321,324 ----
***************
*** 370,387 ****
/*
- * Convert the MIPS hardware trap type code to a Unix signal number.
- */
- static int computeSignal(int tt)
- {
- struct hard_trap_info *ht;
-
- for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
- if (ht->tt == tt)
- return ht->signo;
-
- return SIGHUP; /* default for things we don't know about */
- }
-
- /*
* While we find nice hex chars, build an int.
* Return number of chars processed.
--- 345,348 ----
***************
*** 408,531 ****
}
-
- /*
- * We single-step by setting breakpoints. When an exception
- * is handled, we need to restore the instructions hoisted
- * when the breakpoints were set.
- *
- * This is where we save the original instructions.
- */
- static struct gdb_bp_save {
- unsigned int addr;
- unsigned int val;
- } step_bp[2];
-
- #define BP 0x0000000d /* break opcode */
-
- #if 0
-
- /*
- * Set breakpoint instructions for single stepping.
- */
- static void single_step(struct gdb_regs *regs)
- {
- union mips_instruction insn;
- unsigned int targ;
- int is_branch, is_cond, i;
-
- targ = regs->cp0_epc;
- insn.word = *(unsigned int *)targ;
- is_branch = is_cond = 0;
-
- switch (insn.i_format.opcode) {
- /*
- * jr and jalr are in r_format format.
- */
- case spec_op:
- switch (insn.r_format.func) {
- case jalr_op:
- case jr_op:
- targ = *(®s->reg0 + insn.r_format.rs);
- is_branch = 1;
- break;
- }
- break;
-
- /*
- * This group contains:
- * bltz_op, bgez_op, bltzl_op, bgezl_op,
- * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
- */
- case bcond_op:
- is_branch = is_cond = 1;
- targ += 4 + (insn.i_format.simmediate << 2);
- break;
-
- /*
- * These are unconditional and in j_format.
- */
- case jal_op:
- case j_op:
- is_branch = 1;
- targ += 4;
- targ >>= 28;
- targ <<= 28;
- targ |= (insn.j_format.target << 2);
- break;
-
- /*
- * These are conditional.
- */
- case beq_op:
- case beql_op:
- case bne_op:
- case bnel_op:
- case blez_op:
- case blezl_op:
- case bgtz_op:
- case bgtzl_op:
- case cop0_op:
- case cop1_op:
- case cop2_op:
- case cop1x_op:
- is_branch = is_cond = 1;
- targ += 4 + (insn.i_format.simmediate << 2);
- break;
- }
-
- if (is_branch) {
- i = 0;
- if (is_cond && targ != (regs->cp0_epc + 8)) {
- step_bp[i].addr = regs->cp0_epc + 8;
- step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8);
- *(unsigned *)(regs->cp0_epc + 8) = BP;
- }
- step_bp[i].addr = targ;
- step_bp[i].val = *(unsigned *)targ;
- *(unsigned *)targ = BP;
- } else {
- step_bp[0].addr = regs->cp0_epc + 4;
- step_bp[0].val = *(unsigned *)(regs->cp0_epc + 4);
- *(unsigned *)(regs->cp0_epc + 4) = BP;
- }
- }
-
- /*
- * If asynchronously interrupted by gdb, then we need to set a breakpoint
- * at the interrupted instruction so that we wind up stopped with a
- * reasonable stack frame.
- */
- static struct gdb_bp_save async_bp;
-
- void set_async_breakpoint(unsigned int epc)
- {
- async_bp.addr = epc;
- async_bp.val = *(unsigned *)epc;
- *(unsigned *)epc = BP;
- flush_cache_all();
- }
-
- #endif
-
/*
* This function does all command processing for interfacing to gdb. It
--- 369,372 ----
***************
*** 535,544 ****
void gdb_handle_exception (struct pt_regs *regs)
{
- int trap; /* Trap type */
int sigval;
int addr;
int length;
char *ptr;
- unsigned long *stack;
unsigned regno;
int value;
--- 376,383 ----
***************
*** 549,560 ****
#if 0
- putDebugChar('S');
- putDebugChar('C');
- putDebugChar('O');
- putDebugChar('T');
- putDebugChar('T');
- putDebugChar('\n');
- #endif
- #if 0
printk("in gdb_handle_exception()\n");
#endif
--- 388,391 ----
***************
*** 565,662 ****
regs->pc += 3; /* breakpoint() uses a 3-byte break insn */
- #if 0
- /*
- * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1,
- * the simply switch the FPU on and return since this is no error
- * condition. kernel/traps.c does the same.
- * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE
- * traps for now.
- */
- trap = (regs->cp0_cause & 0x7c) >> 2;
- /* printk("trap=%d\n",trap); */
- if (trap == 11) {
- if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) {
- regs->cp0_status |= ST0_CU1;
- return;
- }
- }
-
- /*
- * If we're in breakpoint() increment the PC
- */
- if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
- regs->cp0_epc += 4;
-
- /*
- * If we were single_stepping, restore the opcodes hoisted
- * for the breakpoint[s].
- */
- if (step_bp[0].addr) {
- *(unsigned *)step_bp[0].addr = step_bp[0].val;
- step_bp[0].addr = 0;
-
- if (step_bp[1].addr) {
- *(unsigned *)step_bp[1].addr = step_bp[1].val;
- step_bp[1].addr = 0;
- }
- }
-
- /*
- * If we were interrupted asynchronously by gdb, then a
- * breakpoint was set at the EPC of the interrupt so
- * that we'd wind up here with an interesting stack frame.
- */
- if (async_bp.addr) {
- *(unsigned *)async_bp.addr = async_bp.val;
- async_bp.addr = 0;
- }
-
- stack = (long *)regs->reg29; /* stack ptr */
- sigval = computeSignal(trap);
-
- /*
- * reply to host that an exception has occurred
- */
- ptr = output_buffer;
-
- /*
- * Send trap type (converted to signal)
- */
- *ptr++ = 'T';
- *ptr++ = hexchars[sigval >> 4];
- *ptr++ = hexchars[sigval & 0xf];
-
- /*
- * Send Error PC
- */
- *ptr++ = hexchars[REG_EPC >> 4];
- *ptr++ = hexchars[REG_EPC & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)®s->cp0_epc, ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send frame pointer
- */
- *ptr++ = hexchars[REG_FP >> 4];
- *ptr++ = hexchars[REG_FP & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)®s->reg30, ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send stack pointer
- */
- *ptr++ = hexchars[REG_SP >> 4];
- *ptr++ = hexchars[REG_SP & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)®s->reg29, ptr, 4, 0);
- *ptr++ = ';';
-
- *ptr++ = 0;
- putpacket(output_buffer); /* send it off... */
-
- #endif
-
sigval = 5;
ptr = output_buffer;
--- 396,399 ----
***************
*** 692,730 ****
*/
case 'g':
! #if 0
! ptr = output_buffer;
! ptr = mem2hex((char *)®s->reg0, ptr, 32*4, 0); /* r0...r31 */
! ptr = mem2hex((char *)®s->cp0_status, ptr, 6*4, 0); /* cp0 */
! ptr = mem2hex((char *)®s->fpr0, ptr, 32*4, 0); /* f0...31 */
! ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*4, 0); /* cp1 */
! ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*4, 0); /* frp */
! ptr = mem2hex((char *)®s->cp0_index, ptr, 16*4, 0); /* cp0 */
! #endif
break;
/*
* set the value of the CPU registers - return OK
- * FIXME: Needs to be written
*/
case 'G':
! {
! #if 0
! unsigned long *newsp, psr;
!
! ptr = &input_buffer[1];
! hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
!
! /*
! * See if the stack pointer has moved. If so, then copy the
! * saved locals and ins to the new location.
! */
!
! newsp = (unsigned long *)registers[SP];
! if (sp != newsp)
! sp = memcpy(newsp, sp, 16 * 4);
!
! #endif
! strcpy(output_buffer,"OK");
! }
break;
--- 429,441 ----
*/
case 'g':
! /* Not supported */
!
break;
/*
* set the value of the CPU registers - return OK
*/
case 'G':
! /* Not supported */
break;
***************
*** 819,826 ****
*/
case 's':
! /*
! * There is no single step insn in the MIPS ISA, so we
! * use breakpoints and continue, instead.
! */
kernel_single_step = 1;
--- 530,536 ----
*/
case 's':
! /* We set a flag here that is read by the exception
! * handler, which will set up ICOUNT/ICOUNTLEVEL
! * correctly. */
kernel_single_step = 1;
***************
*** 859,862 ****
--- 569,587 ----
output_buffer, 4, 0);
}
+ else if (user_mode(regs)) {
+ if (a_reg >= first_pane*4) {
+ if (first_pane < 0)
+ strcpy(output_buffer, "E01");
+ else
+ mem2hex((char *)&(current->thread.regfile[a_reg - first_pane*4]), output_buffer, 4, 0);
+ }
+ else {
+ strcpy(output_buffer, "E01");
+ }
+ }
+ else {
+ mem2hex((char *)&(saved_ar_regs[regno - REG_AR_BASE]), output_buffer, 4, 0);
+ }
+ #if 0
#if 1
else
***************
*** 868,871 ****
--- 593,598 ----
else
#endif
+ #endif
+
#if 0
mem2hex((char *)&(regs->aregs[regno - REG_AR_BASE - regs->wb]), output_buffer, 4, 0);
Index: handlers.S
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/handlers.S,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** handlers.S 19 Sep 2002 07:06:11 -0000 1.3
--- handlers.S 22 Sep 2002 21:18:02 -0000 1.4
***************
*** 1013,1016 ****
--- 1013,1104 ----
#endif /* XCHAL_EXTRA_SA_SIZE */
+ #ifdef CONFIG_KGDB
+ /* When a kernel debug exception is taken with kgdb enabled, we must
+ * save the "ar" registers, since they are not saved by default on
+ * kernel exceptions. On user debug exceptions, we don't have to do
+ * this, since the "ar" registers are saved.
+ *
+ * We save all panes except for the one corresponding to a0-a3. We
+ * don't really need to save the panes for a4-a15, since a0-a15, are
+ * saved in pt_regs, but we do anyway because it makes the algorithm
+ * simpler.
+ * The algoritm is to first save all panes lower than the active one,
+ * and then save all the panes above the active one. We can only touch
+ * a2 and a3. */
+
+ movi a2, return_from_debug_flag // if flag not set
+ l32i a2, a2, 0 // don't spill ar regs
+ beqz kgdb_nospill
+
+ movi a2, saved_ar_regs // get point to save area
+ rsr a3, WINDOWSTART // save window start
+ s32i a3, a2, (XCHAL_NUM_AREGS +1 ) * 4
+ rsr a3, WINDOWBASE // save window base
+ s32i a3, a2, XCHAL_NUM_AREGS * 4
+ beqz a3, kgdb_done_lower // active pane is 0
+ addi a3, a3, -1 // a3 acts as counter
+ slli a3, a3, 4 // 1st pane to save is one
+ add a2, a2, a3 // below the active one
+
+ kgdb_spill_lower:
+
+ rotw -1 // rotate one pane down
+
+ s32i a0, a6, 0 // save this pane
+ s32i a1, a6, 4
+ s32i a2, a6, 8
+ s32i a3, a6, 12
+
+ beqz a7, kgdb_done_lower // pane 0 is the last one below active
+ add a3, a7, -16 // set up the counter/pointer for the
+ add a2, a6, -16 // next frame
+
+ j kgdb_spill_lower
+
+ kgdb_done_lower:
+
+ movi a7, XHCAL_NUM_AREGS / 4 - 1 // set wb to top pane
+ wsr a7, WINDOWBASE
+ rsync
+
+ movi a6, saved_ar_regs
+ addi a6, a6, XCHAL_NUM_AREGS * // set up pointer to saved wb
+ l32i a7, a6, 0 // and read wb into a7
+ addi a7, a7, -(XCHAL_NUM_AREGS / 4 - 1)
+ neg a7 // a7 = total panes - 1 - wb
+ addi a6, -16 // a6 = top pane save area
+
+ kgdb_spill_upper:
+
+ beqz a7, kgdb_done // when counter is 0, we're done
+
+ s32i a0, a6, 0 // save pane
+ s32i a1, a6, 4
+ s32i a2, a6, 8
+ s32i a3, a6, 12
+
+ add a3, a7, -1 // decrement counter
+ add a2, a6, -16 // decrement save area pointer by 1 pane
+
+ rotw -1 // rotate one pane down
+
+ j kgdb_spill_upper
+
+ kgdb_done:
+
+ movi a6, XCHAL_NUM_AREGS * 4
+ l32i a6, a6, 0 // a6 = saved wb
+ wsr a6, WINDOWBASE // restore wb
+ rsync
+
+ movi a7, 1 // make exactly 1 pane valid
+ ssl a6
+ sll a7, a7
+ wsr a7, WINDOWSTART
+ rsync
+
+ kgdb_nospill:
+ #endif /* CONFIG_KGDB */
+
_excMoreCommonException:
***************
*** 1374,1377 ****
--- 1462,1538 ----
#endif /* XCHAL_EXTRA_SA_SIZE */
+
+
+ #ifdef CONFIG_KGDB
+ /* This is the reverse of saving the "ar" registers. See the above
+ * KGDB section for more details. */
+
+ movi a2, return_from_debug_flag // if flag not set
+ l32i a2, a2, 0 // ar regs weren't spilled
+ beqz kgdb_nounspill
+
+ rsr a11, WINDOWBASE // get current wb
+ slli a11, a11, 4 // multiply by 16
+ movi a10, saved_ar_regs // pointer to save area
+ add a10, a10, a11 // adjust to a0-a3 pane
+ addi a10, a10, 16 // now one above a0-a3 pane
+ add a11, a11, -((XCHAL_NUM_AREGS - 4) * 4)
+ neg a11 // a11 = total panes - 1 - wb
+
+ kgdb_unspill_upper:
+ beqz a11, kgdb_undone_upper // counter = 0 means we're done
+
+ rotw 1 // rotate up one pane
+
+ l32i a0, a6, 0 // restore the pane
+ l32i a1, a6, 4
+ l32i a2, a6, 8
+ l32i a3, a6, 12
+
+ addi a10, a6, 16 // set up the next save area
+ addi a11, a7, -16 // decrement the counter
+ j kgdb_unspill_upper
+
+ kgdb_undone_upper:
+
+ movi a7, 0 // set wb = 0, to start saving bottom
+ wsr a7, WINDOWBASE // pane
+ rsync
+
+ movi a6, saved_ar_regs // a6 = bottom (pane 0) of save area
+ l32i a7, a6, XCHAL_NUM_AREGS * 4 // a = saved wb
+ beqz kgdb_unspill_done // if it is 0, nothing below to restore
+ addi a7, a7, -1 // decrement counter
+
+ kgdb_unspill_lower:
+
+ l32i a0, a6, 0 // restore pane
+ l32i a1, a6, 4
+ l32i a2, a6, 8
+ l32i a3, a6, 12
+
+ rotw 1 // rotate up 1 pane
+ beqz a11, kgdb_unspill_done // if counter is 0, we're done
+
+ addi a6, a2, 16 // set up pointer for next pane
+ addi a7, a3, -1 // decrement counter
+
+ j kgdb_unspill_lower
+
+ kgdb_unspill_done:
+ /* wb should be back to original value at this point. We probably
+ * don't need to restore it, but we do anyway. */
+
+ movi a2, saved_ar_regs // restore ws
+ l32i a3, a2, (XCHAL_NUM_AREGS + 1) * 4
+ wsr a3, WINDOWSTART
+ rsync
+
+ l32i a3, a2, XCHAL_NUM_AREGS * 4 // restore wb
+ wsr a3, WINDOWBASE
+ rsync
+
+ kgdb_nounspill:
+ #endif /* CONFIG_KGDB */
l32i a2, a1, PT_WMASK // for quick_unspill case later..
***************
*** 2002,2012 ****
isync
- #ifdef CONFIG_KGDB
- // Save all the ar registers on a debug exception.
- j debug_save_ar_regs
-
- dsar_ret:
- #endif
-
movi a0, handle_debug // re-setup handler and
xsr a0, EXCSAVE + XCHAL_DEBUGLEVEL // restore a0
--- 2163,2166 ----
***************
*** 2018,2028 ****
j _excCommonException // jump to common exception code
-
- #ifdef CONFIG_KGDB
- // This just saves all the ar registers sequentially on debug exceptions.
- debug_save_ar_regs:
-
- j dsar_ret
- #endif // CONFIG_KGDB
/* Only if coprocessors exist to we include handlers for Coprocessor
--- 2172,2175 ----
|
|
From: <sfo...@us...> - 2002-09-19 07:06:43
|
Update of /cvsroot/xtensa/linux/arch/xtensa In directory usw-pr-cvs1:/tmp/cvs-serv975/arch/xtensa Modified Files: config.in Log Message: First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.) Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized. To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb. Index: config.in =================================================================== RCS file: /cvsroot/xtensa/linux/arch/xtensa/config.in,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** config.in 28 Aug 2002 16:10:13 -0000 1.1.1.1 --- config.in 19 Sep 2002 07:06:10 -0000 1.2 *************** *** 186,190 **** bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ ! bool 'Enable remote debugging' CONFIG_XTENSA_REMOTE_DEBUG endmenu --- 186,190 ---- bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ ! bool 'Enable remote debugging' CONFIG_KGDB endmenu |
|
From: <sfo...@us...> - 2002-09-19 07:06:42
|
Update of /cvsroot/xtensa/linux/include/asm-xtensa In directory usw-pr-cvs1:/tmp/cvs-serv975/include/asm-xtensa Modified Files: ptrace.h Log Message: First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.) Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized. To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb. Index: ptrace.h =================================================================== RCS file: /cvsroot/xtensa/linux/include/asm-xtensa/ptrace.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ptrace.h 29 Aug 2002 21:45:56 -0000 1.2 --- ptrace.h 19 Sep 2002 07:06:08 -0000 1.3 *************** *** 33,36 **** --- 33,43 ---- #define SYSCALL_NR 0x1 + /* Note: can return illegal A reg numbers, i.e. > 15 */ + #define AR_REGNO_TO_A_REGNO(ar_regno, wb) \ + ((ar_regno - wb*4) >= 0 ? \ + ar_regno - wb*4 : \ + XCHAL_NUM_AREGS + ar_regno - wb*4) + + /* Offsets from EXCSAVE_1 value: */ #define TABLE_SAVEA0 0 |
|
From: <sfo...@us...> - 2002-09-19 07:06:15
|
Update of /cvsroot/xtensa/linux/arch/xtensa/platform-xt2000
In directory usw-pr-cvs1:/tmp/cvs-serv975/arch/xtensa/platform-xt2000
Modified Files:
Makefile
Added Files:
gdb_hook.c
Log Message:
First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.)
Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized.
To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb.
--- NEW FILE: gdb_hook.c ---
/*
* arch/platform-xt2000/gdb_hook.c
*
* Derived from MIPS.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 Tensilica Inc.
* Authors: Scott Foehner <sfo...@te...>
*/
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#include <asm/io.h>
static struct serial_state rs_table[RS_TABLE_SIZE] = {
SERIAL_PORT_DFNS /* Defined in serial.h */
};
static struct async_struct kdb_port_info = {0};
static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
{
#if 0
return inb(info->port + offset);
#else
return readb((unsigned long) info->iomem_base + (offset<<info->iomem_reg_shift));
#endif
}
static __inline__ void serial_out(struct async_struct *info, int offset,
int value)
{
#if 0
printk("serial_out: port: 0x%08lx iomem_base: %08lx iomem_reg_shift: %d\n", info->port, info->iomem_base, info->iomem_reg_shift);
#endif
#if 0
outb(value, info->port+offset);
#else
writeb(value, (unsigned long) info->iomem_base + (offset<<info->iomem_reg_shift));
#endif
}
void rs_kgdb_hook(int tty_no) {
int t;
struct serial_state *ser = &rs_table[tty_no];
kdb_port_info.state = ser;
kdb_port_info.magic = SERIAL_MAGIC;
kdb_port_info.port = ser->port;
kdb_port_info.flags = ser->flags;
kdb_port_info.iomem_base = ser->iomem_base;
kdb_port_info.iomem_reg_shift = ser->iomem_reg_shift;
/*
* Clear all interrupts
*/
serial_in(&kdb_port_info, UART_LSR);
serial_in(&kdb_port_info, UART_RX);
serial_in(&kdb_port_info, UART_IIR);
serial_in(&kdb_port_info, UART_MSR);
/*
* Now, initialize the UART
*/
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
if (kdb_port_info.flags & ASYNC_FOURPORT) {
kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
t = UART_MCR_DTR | UART_MCR_OUT1;
} else {
kdb_port_info.MCR
= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
t = UART_MCR_DTR | UART_MCR_RTS;
}
kdb_port_info.MCR = t; /* no interrupts, please */
serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
/*
* and set the speed of the serial port
* (currently hardwired to 9600 8N1
*/
/* baud rate is fixed to 9600 (is this sufficient?)*/
t = kdb_port_info.state->baud_base / 9600;
#if 0
printk("BAUD BASE: %d\n", kdb_port_info.state->baud_base);
#endif
/* set DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
/* reset DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
}
int rs_putDebugChar(char c)
{
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
/* Compiler might not think this is volatile, so might want to
* re-code as in rs_getDebugChar below. */
#if 0
while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
;
#else
retry:
if ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
goto retry;
#endif
serial_out(&kdb_port_info, UART_TX, c);
#if 0
printk("putDebugChar: \'%c\'\n", c);
#endif
return 1;
}
char rs_getDebugChar(void)
{
char c;
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
#if 0
while (!((volatile)serial_in(&kdb_port_info, UART_LSR) & UART_LSR_DR))
;
#else
/* Compiler does not seem to think above is volatile, so it
* generates a never-ending loop, i.e., it only reads the
* memory value into the register once. The below code
* seems to generate machine code that re-reads the memory
* every time through the loop.
* Turns out this is not a compiler problem, but rather a problem with * the macro definitions, which "define out" the volatile cast. */
retry:
if ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_DR) == 0)
goto retry;
#endif
#if 1
return(serial_in(&kdb_port_info, UART_RX));
#else
c = serial_in(&kdb_port_info, UART_RX);
printk("getDebugChar: \'%c\'\n", c);
return c;
#endif
}
int putDebugChar(char c)
{
return rs_putDebugChar(c);
}
char getDebugChar(void)
{
return rs_getDebugChar();
}
Index: Makefile
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/platform-xt2000/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** Makefile 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- Makefile 19 Sep 2002 07:06:12 -0000 1.2
***************
*** 13,16 ****
--- 13,17 ----
obj-y = time.o setup.o xt2000-i2cdev.o
obj-$(CONFIG_PCI) += pci.o pci_v320usc.o ../kernel/pci-auto.o
+ obj-$(CONFIG_KGDB) += gdb_hook.o
include $(TOPDIR)/Rules.make
|
|
From: <sfo...@us...> - 2002-09-19 07:06:15
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv975/arch/xtensa/kernel
Modified Files:
Makefile gdb-stub.c handlers.S ptrace.c traps.c
Log Message:
First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.)
Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized.
To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb.
Index: Makefile
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** Makefile 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- Makefile 19 Sep 2002 07:06:11 -0000 1.2
***************
*** 19,23 ****
# obj-$(CONFIG_BOOTSTRAP) += bootstrap.o
! obj-$(CONFIG_XTENSA_REMOTE_DEBUG) += gdb-stub.o
obj-$(CONFIG_PCI) += pci-dma.o pcibios.o
obj-$(CONFIG_PROC_FS) += proc.o
--- 19,23 ----
# obj-$(CONFIG_BOOTSTRAP) += bootstrap.o
! obj-$(CONFIG_KGDB) += gdb-stub.o
obj-$(CONFIG_PCI) += pci-dma.o pcibios.o
obj-$(CONFIG_PROC_FS) += proc.o
Index: gdb-stub.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/gdb-stub.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** gdb-stub.c 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- gdb-stub.c 19 Sep 2002 07:06:11 -0000 1.2
***************
*** 1,17 ****
/*
! * arch/mips/kernel/gdb-stub.c
! *
! * Originally written by Glenn Engel, Lake Stevens Instrument Division
! *
! * Contributed by HP Systems
! *
! * Modified for SPARC by Stu Grossman, Cygnus Support.
*
! * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
! * Send complaints, suggestions etc. to <an...@wa...>
*
! * Copyright (C) 1995 Andreas Busse
*
! * Modified for Linux/Xtensa by Scott Foehner <sfo...@te...>
*/
--- 1,13 ----
/*
! * arch/xtensa/gdb-stub.c
*
! * Derived from MIPS.
*
! * This file is subject to the terms and conditions of the GNU General Public
! * License. See the file "COPYING" in the main directory of this archive
! * for more details.
*
! * Copyright (C) 2001 Tensilica Inc.
! * Authors: Scott Foehner <sfo...@te...>
*/
***************
*** 29,32 ****
--- 25,32 ----
* command function Return value
*
+ * pNN..NN return the value of register hex data or ENN
+ * number NN..NN
+ * PNN..NN:V..V set the value of register number OK or ENN
+ * NN..NN to value V..V
* g return the value of the CPU registers hex data or ENN
* G set the value of the CPU registers OK or ENN
***************
*** 41,50 ****
* sAA..AA Step one instruction from AA..AA SNN
*
! * k kill
*
* ? What was the last sigval ? SNN (signal NN)
*
- * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
- * baud rate
*
* All commands and responses are sent with a packet which includes a
--- 41,50 ----
* sAA..AA Step one instruction from AA..AA SNN
*
! * k kill -- ignored
! *
! * D detach -- resume execution
*
* ? What was the last sigval ? SNN (signal NN)
*
*
* All commands and responses are sent with a packet which includes a
***************
*** 65,123 ****
* $m0,10#2a +$00010203040506070809101112131415#42
*
- *
- * ==============
- * MORE EXAMPLES:
- * ==============
- *
- * For reference -- the following are the steps that one
- * company took (RidgeRun Inc) to get remote gdb debugging
- * going. In this scenario the host machine was a PC and the
- * target platform was a Galileo EVB64120A MIPS evaluation
- * board.
- *
- * Step 1:
- * First download gdb-5.0.tar.gz from the internet.
- * and then build/install the package.
- *
- * Example:
- * $ tar zxf gdb-5.0.tar.gz
- * $ cd gdb-5.0
- * $ ./configure --target=mips-linux-elf
- * $ make
- * $ install
- * $ which mips-linux-elf-gdb
- * /usr/local/bin/mips-linux-elf-gdb
- *
- * Step 2:
- * Configure linux for remote debugging and build it.
- *
- * Example:
- * $ cd ~/linux
- * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- * $ make dep; make vmlinux
- *
- * Step 3:
- * Download the kernel to the remote target and start
- * the kernel running. It will promptly halt and wait
- * for the host gdb session to connect. It does this
- * since the "Kernel Hacking" option has defined
- * CONFIG_REMOTE_DEBUG which in turn enables your calls
- * to:
- * set_debug_traps();
- * breakpoint();
- *
- * Step 4:
- * Start the gdb session on the host.
- *
- * Example:
- * $ mips-linux-elf-gdb vmlinux
- * (gdb) set remotebaud 115200
- * (gdb) target remote /dev/ttyS1
- * ...at this point you are connected to
- * the remote target and can use gdb
- * in the normal fasion. Setting
- * breakpoints, single stepping,
- * printing variables, etc.
- *
*/
--- 65,68 ----
***************
*** 133,136 ****
--- 78,82 ----
#include <asm/pgtable.h>
#include <asm/system.h>
+ #include <asm/ptrace.h>
/*
***************
*** 140,144 ****
extern int putDebugChar(char c); /* write a single character */
extern char getDebugChar(void); /* read and return a single char */
- extern void trap_low(void);
/*
--- 86,89 ----
***************
*** 147,151 ****
extern void breakpoint(void);
extern void breakinst(void);
- extern void adel(void);
/*
--- 92,95 ----
***************
*** 172,175 ****
--- 116,130 ----
static const char hexchars[]="0123456789abcdef";
+ int gdb_enter = 0; /* when set, kernel waits for connection from gdb on boot */
+
+ int kernel_single_step = 0; /* when set, kernel should single step */
+
+ /* saved_ar_regs provide a buffer to save the ar registers on debug
+ * exceptions. */
+ int saved_ar_regs[XCHAL_NUM_AREGS];
+ /* return_from_debug_flag is used to signal the exception handler to restore
+ * the ar registers from saved_ar_regs on return. */
+ int return_from_debug_flag = 0;
+
/* Used to prevent crashes in memory access. Note that they'll crash anyway if
we haven't set up fault handlers yet... */
***************
*** 316,321 ****
* Return a pointer to the last char put in buf (null), in case of mem fault,
* return 0.
! * may_fault is non-zero if we are reading from arbitrary memory, but is currently
! * not used.
*/
static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
--- 271,276 ----
* Return a pointer to the last char put in buf (null), in case of mem fault,
* return 0.
! * may_fault is non-zero if we are reading from arbitrary memory, but is
! * currently not used.
*/
static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
***************
*** 337,343 ****
/*
* convert the hex array pointed to by buf into binary to be placed in mem
! * return a pointer to the character AFTER the last byte written
! * may_fault is non-zero if we are reading from arbitrary memory, but is currently
! * not used.
*/
static char *hex2mem(char *buf, char *mem, int count, int may_fault)
--- 292,298 ----
/*
* convert the hex array pointed to by buf into binary to be placed in mem
! * Return a pointer to the character AFTER the last byte written
! * may_fault is non-zero if we are reading from arbitrary memory, but is
! * currently not used.
*/
static char *hex2mem(char *buf, char *mem, int count, int may_fault)
***************
*** 380,401 ****
};
- /* Save the normal trap handlers for user-mode traps. */
- void *saved_vectors[32];
/*
* Set up exception handlers for tracing and breakpoints
*/
void set_debug_traps(void)
{
- struct hard_trap_info *ht;
unsigned long flags;
unsigned char c;
- save_and_cli(flags);
#if 0
! for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
! saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
#endif
!
putDebugChar('+'); /* 'hello world' */
/*
--- 335,355 ----
};
/*
* Set up exception handlers for tracing and breakpoints
+ *
+ * Linux/Xtensa has a dedicated debug handler that is always there, so we don't
+ * have to set up a handler here.
*/
void set_debug_traps(void)
{
unsigned long flags;
unsigned char c;
#if 0
! printk("in set_debug_traps\n");
#endif
! save_and_cli(flags);
!
putDebugChar('+'); /* 'hello world' */
/*
***************
*** 403,406 ****
--- 357,361 ----
* (presumably "$?#xx") sitting there.
*/
+ #if 0
while((c = getDebugChar()) != '$');
while((c = getDebugChar()) != '#');
***************
*** 408,411 ****
--- 363,367 ----
c = getDebugChar(); /* eat second csum byte */
putDebugChar('+'); /* ack it */
+ #endif
initialized = 1;
***************
*** 453,487 ****
- #if 0
- /*
- * Print registers (on target console)
- * Used only to debug the stub...
- */
- void show_gdbregs(struct gdb_regs * regs)
- {
- /*
- * Saved main processor registers
- */
- printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg0, regs->reg1, regs->reg2, regs->reg3,
- regs->reg4, regs->reg5, regs->reg6, regs->reg7);
- printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg8, regs->reg9, regs->reg10, regs->reg11,
- regs->reg12, regs->reg13, regs->reg14, regs->reg15);
- printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg16, regs->reg17, regs->reg18, regs->reg19,
- regs->reg20, regs->reg21, regs->reg22, regs->reg23);
- printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg24, regs->reg25, regs->reg26, regs->reg27,
- regs->reg28, regs->reg29, regs->reg30, regs->reg31);
-
- /*
- * Saved cp0 registers
- */
- printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n",
- regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
- }
- #endif /* dead code */
-
/*
* We single-step by setting breakpoints. When an exception
--- 409,412 ----
***************
*** 616,624 ****
char *ptr;
unsigned long *stack;
- printk("in handle_exception()\n");
#if 0
! show_gdbregs(regs);
#endif
#if 0
--- 541,567 ----
char *ptr;
unsigned long *stack;
+ unsigned regno;
+ int value;
+ int ar_reg, a_reg, first_pane;
+ extern int find_first_pane(int, int);
+
+ kernel_single_step = 0;
#if 0
! putDebugChar('S');
! putDebugChar('C');
! putDebugChar('O');
! putDebugChar('T');
! putDebugChar('T');
! putDebugChar('\n');
! #endif
! #if 0
! printk("in gdb_handle_exception()\n");
#endif
+ /*
+ * If we're in breakpoint() increment the PC
+ */
+ if (regs->pc == (unsigned long)breakinst)
+ regs->pc += 3; /* breakpoint() uses a 3-byte break insn */
#if 0
***************
*** 714,717 ****
--- 657,671 ----
putpacket(output_buffer); /* send it off... */
+ #endif
+
+ sigval = 5;
+ ptr = output_buffer;
+
+ *ptr++ = 'S';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+ *ptr++ = 0;
+ putpacket(output_buffer); /* send it off... */
+
/*
* Wait for input from remote GDB
***************
*** 738,741 ****
--- 692,696 ----
*/
case 'g':
+ #if 0
ptr = output_buffer;
ptr = mem2hex((char *)®s->reg0, ptr, 32*4, 0); /* r0...r31 */
***************
*** 745,748 ****
--- 700,704 ----
ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*4, 0); /* frp */
ptr = mem2hex((char *)®s->cp0_index, ptr, 16*4, 0); /* cp0 */
+ #endif
break;
***************
*** 806,809 ****
--- 762,775 ----
else
strcpy(output_buffer, "E02");
+
+ /* We need to write back any data in the writeback
+ * cache, and invalidate the instruction cache, in
+ * case we are writing instructions to memory. */
+ /* For now, writeback/invalidate the whole cache,
+ * although we should probably only do the appropriate
+ * line (or lines). */
+ xthal_dcache_all_writeback();
+ xthal_icache_all_invalidate();
+
break;
***************
*** 814,820 ****
--- 780,788 ----
/* try to read optional parameter, pc unchanged if no parm */
+ #if 0
ptr = &input_buffer[1];
if (hexToInt(&ptr, &addr))
regs->cp0_epc = addr;
+ #endif
/*
***************
*** 832,848 ****
break;
-
/*
! * kill the program
*/
! case 'k' :
! break; /* do nothing */
/*
! * Reset the whole machine (FIXME: system dependent)
*/
! case 'r':
! break;
--- 800,816 ----
break;
/*
! * Detach and continue running
*/
! case 'D':
! return; /* resume execution */
+ /* NOTREACHED */
/*
! * kill the program
*/
! case 'k':
! break; /* do nothing */
***************
*** 855,907 ****
* use breakpoints and continue, instead.
*/
! single_step(regs);
! flush_cache_all();
return;
/* NOTREACHED */
- /*
- * Set baud rate (bBB)
- * FIXME: Needs to be written
- */
- case 'b':
- {
- #if 0
- int baudrate;
- extern void set_timer_3();
! ptr = &input_buffer[1];
! if (!hexToInt(&ptr, &baudrate))
! {
! strcpy(output_buffer,"B01");
! break;
! }
! /* Convert baud rate to uart clock divider */
! switch (baudrate)
! {
! case 38400:
! baudrate = 16;
! break;
! case 19200:
! baudrate = 33;
! break;
! case 9600:
! baudrate = 65;
! break;
! default:
! baudrate = 0;
! strcpy(output_buffer,"B02");
! goto x1;
! }
! if (baudrate) {
! putpacket("OK"); /* Ack before changing speed */
! set_timer_3(baudrate); /* Set it */
! }
#endif
! }
break;
} /* switch */
--- 823,1031 ----
* use breakpoints and continue, instead.
*/
!
! kernel_single_step = 1;
return;
+
/* NOTREACHED */
! case 'H':
! output_buffer[0] = 'O';
! output_buffer[1] = 'K';
! output_buffer[2] = 0;
! break;
! case 'p':
! ptr = &input_buffer[1];
! hexToInt(&ptr, ®no);
! #if 0
! printk("p regno: 0x%x\n", regno);
! #endif
! switch(regno) {
! case REG_A_BASE ... REG_A_BASE + 15:
! mem2hex((char *)&(regs->aregs[regno - REG_A_BASE]),
! output_buffer, 4, 0);
! break;
! case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
! /* If we want one of the AR regs that falls within
! * the register window, we should get the
! * corresponding A reg. */
! ar_reg = regno - REG_AR_BASE;
! a_reg = AR_REGNO_TO_A_REGNO(ar_reg, regs->wb);
! first_pane = find_first_pane(regs->wb, regs->ws);
! if (a_reg < 16) {
! mem2hex((char *)&(regs->aregs[a_reg]),
! output_buffer, 4, 0);
! }
! #if 1
! else
! strcpy(output_buffer, "E01");
! #else
! else if(a_reg >= first_pane*4) {
! if(first_pane < 0)
! strcpy(output_buffer, "E01");
! else
! #endif
! #if 0
! mem2hex((char *)&(regs->aregs[regno - REG_AR_BASE - regs->wb]), output_buffer, 4, 0);
! #endif
! break;
!
! case REG_PC:
! mem2hex((char *)&(regs->pc), output_buffer, 4, 0);
! break;
! case REG_PS:
! mem2hex((char *)&(regs->ps), output_buffer, 4, 0);
! break;
!
! case REG_WB:
! mem2hex((char *)&(regs->wb), output_buffer, 4, 0);
! break;
!
! case REG_WS:
! mem2hex((char *)&(regs->ws), output_buffer, 4, 0);
! break;
!
! case REG_LBEG:
! mem2hex((char *)&(regs->lbeg), output_buffer, 4, 0);
! break;
!
! case REG_LEND:
! mem2hex((char *)&(regs->lend), output_buffer, 4, 0);
! break;
!
! case REG_LCOUNT:
! mem2hex((char *)&(regs->lcount), output_buffer, 4, 0);
! break;
!
! case REG_SAR:
! mem2hex((char *)&(regs->sar), output_buffer, 4, 0);
! break;
!
! case REG_DEPC:
! mem2hex((char *)&(regs->depc), output_buffer, 4, 0);
! break;
!
! case REG_EXCCAUSE:
! mem2hex((char *)&(regs->exccause), output_buffer, 4, 0);
! break;
!
! case REG_EXCVADDR:
! mem2hex((char *)&(regs->excvaddr), output_buffer, 4, 0);
! break;
!
! default:
! strcpy(output_buffer,"ffffffff");
! break;
! }
! break;
!
! case 'P':
! ptr = &input_buffer[1];
! #if 0
! printk("P %s\n", input_buffer);
#endif
! if (hexToInt(&ptr, ®no) && *ptr++ == '='
! && hexToInt(&ptr, &value)) {
! strcpy(output_buffer, "OK");
! } else {
! strcpy(output_buffer, "E01");
! break;
! }
!
! ptr = &input_buffer[1];
! hexToInt(&ptr, ®no);
! printk("P regno: 0x%x\n", regno);
! switch(regno) {
! case REG_A_BASE ... REG_A_BASE + 15:
! mem2hex((char *)&(regs->aregs[regno - REG_A_BASE]),
! output_buffer, 4, 0);
! break;
!
! case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
! mem2hex((char *)&(regs->aregs[regno - REG_AR_BASE - regs->wb]), output_buffer, 4, 0);
! break;
!
! case REG_PC:
! regs->pc = value;
! break;
!
! case REG_PS:
! mem2hex((char *)&(regs->ps), output_buffer, 4, 0);
! break;
!
! case REG_WB:
! mem2hex((char *)&(regs->wb), output_buffer, 4, 0);
! break;
!
! case REG_WS:
! mem2hex((char *)&(regs->ws), output_buffer, 4, 0);
! break;
!
! case REG_LBEG:
! mem2hex((char *)&(regs->lbeg), output_buffer, 4, 0);
! break;
!
! case REG_LEND:
! mem2hex((char *)&(regs->lend), output_buffer, 4, 0);
! break;
!
! case REG_LCOUNT:
! mem2hex((char *)&(regs->lcount), output_buffer, 4, 0);
! break;
!
! case REG_SAR:
! mem2hex((char *)&(regs->sar), output_buffer, 4, 0);
! break;
!
! case REG_DEPC:
! mem2hex((char *)&(regs->depc), output_buffer, 4, 0);
! break;
!
! case REG_EXCCAUSE:
! mem2hex((char *)&(regs->exccause), output_buffer, 4, 0);
! break;
!
! case REG_EXCVADDR:
! mem2hex((char *)&(regs->excvaddr), output_buffer, 4, 0);
! break;
!
! default:
! strcpy(output_buffer,"E01");
! break;
! }
! break;
!
! case 'q':
! if (!strncmp(input_buffer, "qxtn", 4)) {
! #if 0
! output_buffer[0] = 'L';
! output_buffer[1] = 'i';
! output_buffer[2] = 'n';
! output_buffer[3] = 'u';
! output_buffer[4] = 'x';
! output_buffer[5] = 0;
! #else
! output_buffer[0] = 'I';
! output_buffer[1] = 'S';
! output_buffer[2] = 'S';
! output_buffer[3] = '3';
! output_buffer[4] = 0;
! #endif
! strcpy(output_buffer, "XMON2.5");
! }
break;
+ case 'Q':
+ if (!strncmp(input_buffer, "Qxtcs", 4)) {
+ /* We just ignore the toggle save command. Linux
+ * always saves its registers. */
+ output_buffer[0] = 'O';
+ output_buffer[1] = 'K';
+ output_buffer[2] = 0;
+ }
+ break;
} /* switch */
***************
*** 913,917 ****
} /* while */
- #endif
}
--- 1037,1040 ----
***************
*** 926,995 ****
if (!initialized)
return;
-
- printk("In breakpoint() function\n");
#if 0
! __asm__ __volatile__("
! .globl breakinst
! .set noreorder
! nop
! breakinst: break
! nop
! .set reorder
! ");
#endif
! }
!
! #if 0
! void adel(void)
! {
! __asm__ __volatile__("
! .globl adel
! la $8,0x80000001
! lw $9,0($8)
");
}
- #endif
-
- #ifdef CONFIG_GDB_CONSOLE
-
- void gdb_puts(const char *str)
- {
- int l = strlen(str);
- char outbuf[18];
-
- outbuf[0]='O';
-
- while(l) {
- int i = (l>8)?8:l;
- mem2hex((char *)str, &outbuf[1], i, 0);
- outbuf[(i*2)+1]=0;
- putpacket(outbuf);
- str += i;
- l -= i;
- }
- }
- static kdev_t gdb_console_dev(struct console *con)
- {
- return MKDEV(1, 3); /* /dev/null */
- }
! static void gdb_console_write(struct console *con, const char *s, unsigned n)
{
! gdb_puts(s);
}
! static struct console gdb_console = {
! name: "gdb",
! write: gdb_console_write,
! device: gdb_console_dev,
! flags: CON_PRINTBUFFER,
! index: -1
! };
- __init void register_gdb_console(void)
- {
- register_console(&gdb_console);
- }
-
- #endif
--- 1049,1067 ----
if (!initialized)
return;
#if 0
! printk("In breakpoint() function\n");
#endif
! __asm__ __volatile__(" \
! breakinst: break 0, 0\n \
");
}
! static int __init kgdb_opt_gdb(void)
{
! gdb_enter = 1;
! return 1;
}
! __setup("gdb", kgdb_opt_gdb);
Index: handlers.S
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/handlers.S,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** handlers.S 29 Aug 2002 21:45:01 -0000 1.2
--- handlers.S 19 Sep 2002 07:06:11 -0000 1.3
***************
*** 16,19 ****
--- 16,20 ----
* Authors: Marc Gauthier
* Joe Taylor <jo...@te..., jo...@ya...>
+ * Scott Foehner <sfo...@te...> (debug handler)
*/
***************
*** 83,86 ****
--- 84,88 ----
.comm kernelsp,4,4 /* kernel stack pointer */
+ .comm kernel_single_step,4,4
***************
*** 584,591 ****
* and natively debugging is not allowed.)
*/
_GET_CURRENT a2
l32i a3, a2, TASK_PTRACE
extui a3, a3, 16, 1 // extract PT_SINGLESTEP flag
! beqz a3, 1f // flag not set
movi a2, 0
wsr a2, ICOUNTLEVEL // turn off instruction counting
--- 586,602 ----
* and natively debugging is not allowed.)
*/
+
+ #if 1
+ rsr a2, DEBUGCAUSE
+ s32i a2, a1, PT_RESERVED1
+ #endif
+
_GET_CURRENT a2
l32i a3, a2, TASK_PTRACE
extui a3, a3, 16, 1 // extract PT_SINGLESTEP flag
! movi a2, kernel_single_step // get kernel stepping flag
! l32i a2, a2, 0
! or a3, a3, a2 // if either set, turn of icounting
! beqz a3, 1f // flags not set
movi a2, 0
wsr a2, ICOUNTLEVEL // turn off instruction counting
***************
*** 1400,1404 ****
// PT_SINGLESTEP is set by sys_ptrace (ptrace.c)
! // Only enable single stepping if returning from a user exception
#if EXCTYPE_USER
bnei a0, EXCTYPE_USER, 4f // Hack around lack of bnei relaxation
--- 1411,1417 ----
// PT_SINGLESTEP is set by sys_ptrace (ptrace.c)
! // Only enable single stepping if returning from a user exception,
! // or it's a kernel exception, and kernel_single_step is set.
! beqi a0, EXCTYPE_KERNEL, 1f // returning from kernel exception?
#if EXCTYPE_USER
bnei a0, EXCTYPE_USER, 4f // Hack around lack of bnei relaxation
***************
*** 1409,1414 ****
l32i a3, a2, TASK_PTRACE
extui a3, a3, 16, 1 // extract PT_SINGLESTEP flag
! beqz a3, 4f // flag not set
movi a3, -2 // PT_SINGLESTEP flag is set,
wsr a3, ICOUNT // so setup icount & icountlevel.
--- 1422,1436 ----
l32i a3, a2, TASK_PTRACE
extui a3, a3, 16, 1 // extract PT_SINGLESTEP flag
! bnez a3, 2f // flag set
! 1:
! movi a3, kernel_single_step // see if kernel should single step
! l32i a3, a3, 0
! beqz a3, 4f // nope
! #if 0
! mov a1, a3
! j CriticalExc
! #endif
+ 2:
movi a3, -2 // PT_SINGLESTEP flag is set,
wsr a3, ICOUNT // so setup icount & icountlevel.
***************
*** 1971,1978 ****
--- 1993,2012 ----
wsr a0, EPC_1 // generic exception code.
rsr a0, EPS + XCHAL_DEBUGLEVEL // Put PS wth EXCM on into PS
+
+ #if 1
+ s32i a0, a1, PT_RESERVED0
+ #endif
+
addi a0, a0, XCHAL_PS_EXCM_MASK // for the generic exception
wsr a0, PS // code.
isync
+ #ifdef CONFIG_KGDB
+ // Save all the ar registers on a debug exception.
+ j debug_save_ar_regs
+
+ dsar_ret:
+ #endif
+
movi a0, handle_debug // re-setup handler and
xsr a0, EXCSAVE + XCHAL_DEBUGLEVEL // restore a0
***************
*** 1984,1987 ****
--- 2018,2028 ----
j _excCommonException // jump to common exception code
+
+ #ifdef CONFIG_KGDB
+ // This just saves all the ar registers sequentially on debug exceptions.
+ debug_save_ar_regs:
+
+ j dsar_ret
+ #endif // CONFIG_KGDB
/* Only if coprocessors exist to we include handlers for Coprocessor
Index: ptrace.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/ptrace.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** ptrace.c 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- ptrace.c 19 Sep 2002 07:06:12 -0000 1.2
***************
*** 30,39 ****
#define PT_SINGLESTEP 0x10000
- /* Note: can return illegal A reg numbers, i.e. > 15 */
- #define AR_REGNO_TO_A_REGNO(ar_regno, wb) \
- ((ar_regno - wb*4) >= 0 ? \
- ar_regno - wb*4 : \
- XCHAL_NUM_AREGS + ar_regno - wb*4)
-
/* Given a valid wb and ws, find the first valid "pane" */
/* Pane is given as the distance from pane 0, which is wb */
--- 30,33 ----
Index: traps.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/traps.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** traps.c 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- traps.c 19 Sep 2002 07:06:12 -0000 1.2
***************
*** 10,14 ****
* Complete output from die() by Ulf Carlsson, 1998
* Copyright (C) 1999 Silicon Graphics, Inc.
! * Copyright (C) 2001 Tensilica Inc., by Joe Taylor, Kevin Chea, Marc Gauthier
*/
--- 10,15 ----
* Complete output from die() by Ulf Carlsson, 1998
* Copyright (C) 1999 Silicon Graphics, Inc.
! * Copyright (C) 2001 Tensilica Inc., by Joe Taylor, Kevin Chea, Marc Gauthier,
! * Scott Foehner
*/
***************
*** 24,27 ****
--- 25,32 ----
#include <asm/xtutil.h>
+ #ifdef CONFIG_KGDB
+ extern int gdb_enter;
+ extern int return_from_debug_flag;
+ #endif
/*
***************
*** 256,295 ****
{
int i;
- #if 0
- printk("\nKERNEL: DO DEBUG\n\n");
- #endif
#if 0
! printk("DEBUGCAUSE: 0x%x ", regs->reserved1);
if(regs->reserved1 & DEBUGCAUSE_DEBUGINT_MASK)
! printk("debug interrupt\n");
if(regs->reserved1 & DEBUGCAUSE_BREAKN_MASK)
! printk("break.n\n");
if(regs->reserved1 & DEBUGCAUSE_BREAK_MASK)
! printk("break\n");
if(regs->reserved1 & DEBUGCAUSE_DBREAK_MASK)
! printk("dbreak\n");
if(regs->reserved1 & DEBUGCAUSE_IBREAK_MASK)
! printk("ibreak\n");
if(regs->reserved1 & DEBUGCAUSE_ICOUNT_MASK)
! printk("icount\n");
! printk("PS: 0x%x\n", regs->ps);
! printk("PTRACE: 0x%x\n", current->ptrace);
#endif
if (user_mode(regs)) {
- /* KGDB: Probably want to put a hook here to kgdb if it is
- * enabled */
/* If in user mode, send SIGTRAP signal to current process */
#if 0
! printk("KERNEL: Breakpoint at '%s' (pid = %d, pc = %#010x)\n",
current->comm, current->pid, regs->pc);
#endif
#if 0
for (i = 0; i < 16; i++) {
! printk("KERNEL: a%02d: 0x%08x\n", i, regs->aregs[i]);
}
#endif
--- 261,314 ----
{
int i;
#if 0
! printk("\nDEBUGCAUSE: 0x%x ", regs->reserved1);
if(regs->reserved1 & DEBUGCAUSE_DEBUGINT_MASK)
! printk("debug interrupt ");
if(regs->reserved1 & DEBUGCAUSE_BREAKN_MASK)
! printk("break.n ");
if(regs->reserved1 & DEBUGCAUSE_BREAK_MASK)
! printk("break ");
if(regs->reserved1 & DEBUGCAUSE_DBREAK_MASK)
! printk("dbreak ");
if(regs->reserved1 & DEBUGCAUSE_IBREAK_MASK)
! printk("ibreak ");
if(regs->reserved1 & DEBUGCAUSE_ICOUNT_MASK)
! printk("icount ");
! printk("PS: 0x%x ", regs->ps);
! printk("ORIG_PS: 0x%x ", regs->reserved0);
! printk("PTRACE: 0x%x ", current->ptrace);
!
! printk("\n");
! #endif
!
! /* If remote debugging is configured AND enabled, we give control to
! * kgdb. Otherwise, we fall through, perhaps giving control to the
! * native debugger. */
! #ifdef CONFIG_KGDB
! if (gdb_enter) {
! extern void gdb_handle_exception(struct pt_regs *);
! gdb_handle_exception(regs);
! return_from_debug_flag = 1;
! return;
! }
#endif
if (user_mode(regs)) {
/* If in user mode, send SIGTRAP signal to current process */
#if 0
! printk("KERNEL: User break at '%s' (pid = %d, pc = %#010x)\n",
current->comm, current->pid, regs->pc);
#endif
#if 0
for (i = 0; i < 16; i++) {
! if ((i % 4) == 0)
! printk("KERNEL: ");
! printk("a%02d: 0x%08x ", i, regs->aregs[i]);
! if ((i % 4) == 3)
! printk("\n");
}
#endif
***************
*** 297,306 ****
} else {
- /* KGDB: Probably want to put a hook here to kgdb if it is
- * enabled */
-
/* If in kernel mode, we're in trouble,
* unless kgdb is enabled */
! #if 0
panic("Breakpoint in kernel (pc = %#010x)", regs->pc);
#else
--- 316,322 ----
} else {
/* If in kernel mode, we're in trouble,
* unless kgdb is enabled */
! #if 1
panic("Breakpoint in kernel (pc = %#010x)", regs->pc);
#else
|
|
From: <sfo...@us...> - 2002-09-19 07:06:15
|
Update of /cvsroot/xtensa/linux/arch/xtensa/mm
In directory usw-pr-cvs1:/tmp/cvs-serv975/arch/xtensa/mm
Modified Files:
init.c
Log Message:
First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.)
Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized.
To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb.
Index: init.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/mm/init.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** init.c 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- init.c 19 Sep 2002 07:06:12 -0000 1.2
***************
*** 527,530 ****
--- 527,549 ----
datasize >> 10,
initsize >> 10);
+
+ /* We put the kgdb hook here, since we want it in arch-specific code, and after
+ * the console has been initialized. Doing this right after the IRQs are
+ * initialized would be ideal, but then the user wouldn't see the
+ * "Waiting for..." message on the console. */
+ #ifdef CONFIG_KGDB
+ extern int gdb_enter;
+ extern void breakpoint(void);
+ extern void set_debug_traps(void);
+ extern void rs_kgdb_hook(int);
+ if (gdb_enter) {
+ rs_kgdb_hook(1);
+ set_debug_traps();
+ printk("Waiting for connection from remote gdb... \n");
+ breakpoint();
+ }
+ #endif
+
+
}
|
|
From: <jgr...@us...> - 2002-09-13 22:44:41
|
Update of /cvsroot/xtensa/linux/include/asm-xtensa
In directory usw-pr-cvs1:/tmp/cvs-serv5463/include/asm-xtensa
Modified Files:
ioctls.h
Log Message:
Add definition for FIOQSIZE.
Index: ioctls.h
===================================================================
RCS file: /cvsroot/xtensa/linux/include/asm-xtensa/ioctls.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** ioctls.h 28 Aug 2002 16:11:31 -0000 1.1.1.1
--- ioctls.h 13 Sep 2002 22:44:39 -0000 1.2
***************
*** 10,13 ****
--- 10,14 ----
#define FIONREAD _IOR('f', 127, int)
#define TIOCINQ FIONREAD
+ #define FIOQSIZE _IOR('f', 128, loff_t)
#define TCGETS 0x5401
|
|
From: <jgr...@us...> - 2002-09-12 18:17:03
|
Update of /cvsroot/xtensa/linux/include/asm-xtensa
In directory usw-pr-cvs1:/tmp/cvs-serv6645/include/asm-xtensa
Modified Files:
uaccess.h
Log Message:
strncpy_from_user(): check access only on first source byte;
count is not necessarily valid for all of source.
Index: uaccess.h
===================================================================
RCS file: /cvsroot/xtensa/linux/include/asm-xtensa/uaccess.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** uaccess.h 28 Aug 2002 16:11:31 -0000 1.1.1.1
--- uaccess.h 12 Sep 2002 18:17:00 -0000 1.2
***************
*** 428,432 ****
strncpy_from_user(char *dst, const char *src, long count)
{
! if (access_ok(VERIFY_READ, src, count))
return __strncpy_from_user(dst, src, count);
return -EFAULT;
--- 428,432 ----
strncpy_from_user(char *dst, const char *src, long count)
{
! if (access_ok(VERIFY_READ, src, 1))
return __strncpy_from_user(dst, src, count);
return -EFAULT;
|
|
From: <jgr...@us...> - 2002-09-12 18:14:14
|
Update of /cvsroot/xtensa/linux/include/asm-xtensa In directory usw-pr-cvs1:/tmp/cvs-serv6017/include/asm-xtensa Modified Files: pgtable.h Log Message: Move vmalloc memory to 0xC0000000 so modules can call kernel code. Index: pgtable.h =================================================================== RCS file: /cvsroot/xtensa/linux/include/asm-xtensa/pgtable.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** pgtable.h 28 Aug 2002 16:11:31 -0000 1.1.1.1 --- pgtable.h 12 Sep 2002 18:14:11 -0000 1.2 *************** *** 86,92 **** #define FIRST_USER_PGD_NR 0 ! #define VMALLOC_START 0xB0010000 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) ! #define VMALLOC_END 0xBFFF0000 /* Xtensa Linux config PTE layout: --- 86,102 ---- #define FIRST_USER_PGD_NR 0 ! /* ! * XTFIXME: The CHAL should provide memory-map info on local memories and ! * XLMI ports that are identity mapped. They are typically located just ! * below the kernel space at 0xD0000000, and they are relatively small ! * (today). We want to verify (with #error directives), however, that ! * these memory-mapped processor features do not overlap the VMALLOC space ! * we define here. [Sep 11, 2002] ! */ ! ! /* 0xC0000000-0xC8000000 reserved for vmalloc; below allows guard memory */ ! #define VMALLOC_START 0xC0010000 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) ! #define VMALLOC_END 0xC7FF0000 /* Xtensa Linux config PTE layout: |
|
From: <jgr...@us...> - 2002-09-11 16:29:55
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel In directory usw-pr-cvs1:/tmp/cvs-serv17320 Modified Files: syscalls.h Log Message: Correct argument count for sys_init_module(). Index: syscalls.h =================================================================== RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/syscalls.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** syscalls.h 28 Aug 2002 16:10:14 -0000 1.1.1.1 --- syscalls.h 11 Sep 2002 16:29:49 -0000 1.2 *************** *** 152,156 **** SYS(sys_sigprocmask, 3) SYS(sys_create_module, 2) ! SYS(sys_init_module, 5) SYS(sys_delete_module, 1) SYS(sys_get_kernel_syms, 1) /* 130 */ --- 152,156 ---- SYS(sys_sigprocmask, 3) SYS(sys_create_module, 2) ! SYS(sys_init_module, 2) SYS(sys_delete_module, 1) SYS(sys_get_kernel_syms, 1) /* 130 */ |
|
From: <joe...@us...> - 2002-09-09 22:23:59
|
Update of /cvsroot/xtensa/linux/arch/xtensa/mm In directory usw-pr-cvs1:/tmp/cvs-serv29181/arch/xtensa/mm Modified Files: fault.c Log Message: In handling page faults, also check the PC of the offending instruction before determining whether it was a kernel or user page fault. This prevents a user program from crashing the kernel with an unmapped address > TASK_SIZE. Index: fault.c =================================================================== RCS file: /cvsroot/xtensa/linux/arch/xtensa/mm/fault.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** fault.c 28 Aug 2002 16:10:14 -0000 1.1.1.1 --- fault.c 9 Sep 2002 22:23:54 -0000 1.2 *************** *** 86,90 **** * 'reference' page table is init_mm.pgd. */ ! if (address >= TASK_SIZE) goto vmalloc_fault; --- 86,90 ---- * 'reference' page table is init_mm.pgd. */ ! if ((address >= TASK_SIZE) && (regs->pc >= TASK_SIZE)) goto vmalloc_fault; |
|
From: <joe...@us...> - 2002-09-09 19:24:14
|
Update of /cvsroot/xtensa/linux/include/asm-xtensa
In directory usw-pr-cvs1:/tmp/cvs-serv2235/include/asm-xtensa
Modified Files:
stat.h
Log Message:
Corrected 'struct stat64' for bi-endian Xtensa. It had a few errors for big-endian processors. I wonder if this will fix any other bugs on our list?? Be sure to reproduce them before debugging them.
Index: stat.h
===================================================================
RCS file: /cvsroot/xtensa/linux/include/asm-xtensa/stat.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** stat.h 28 Aug 2002 16:11:31 -0000 1.1.1.1
--- stat.h 9 Sep 2002 19:24:06 -0000 1.2
***************
*** 51,91 ****
};
! /* This matches struct stat64 in glibc2.1, hence the absolutely
! * insane amounts of padding around dev_t's.
*/
! struct stat64 {
! unsigned short st_dev;
unsigned char __pad0[10];
! unsigned long st_ino;
! unsigned int st_mode;
! unsigned int st_nlink;
! unsigned long st_uid;
! unsigned long st_gid;
! unsigned short st_rdev;
unsigned char __pad3[10];
! long long st_size;
! unsigned long st_blksize;
!
! /* glibc st_blocks are long long; pad for alignment */
! unsigned long __pad4;
!
! unsigned long st_blocks; /* Number 512-byte blocks allocated. */
! unsigned long __pad5; /* future possible st_blocks high bits */
!
! unsigned long st_atime;
! unsigned long __pad6;
!
! unsigned long st_mtime;
! unsigned long __pad7;
! unsigned long st_ctime;
! unsigned long __pad8; /* will be high 32 bits of ctime someday */
! unsigned long __unused1;
! unsigned long __unused2;
};
--- 51,102 ----
};
! /* This matches struct stat64 in glibc-2.2.3
*/
! struct stat64 {
! #ifdef __XTENSA_EL__
! unsigned short st_dev; /* Device */
unsigned char __pad0[10];
+ #else
+ unsigned char __pad0[6];
+ unsigned short st_dev;
+ unsigned char __pad1[2];
+ #endif
! #define STAT64_HAS_BROKEN_ST_INO 1
! unsigned long __st_ino; /* 32bit file serial number. */
! unsigned int st_mode; /* File mode. */
! unsigned int st_nlink; /* Link count. */
! unsigned int st_uid; /* User ID of the file's owner. */
! unsigned int st_gid; /* Group ID of the file's group. */
! #ifdef __XTENSA_EL__
! unsigned short st_rdev; /* Device number, if device. */
unsigned char __pad3[10];
+ #else
+ unsigned char __pad2[6];
+ unsigned short st_rdev;
+ unsigned char __pad3[2];
+ #endif
! long long int st_size; /* Size of file, in bytes. */
! long int st_blksize; /* Optimal block size for I/O. */
! #ifdef __XTENSA_EL__
! unsigned long st_blocks; /* Number 512-byte blocks allocated. */
! unsigned long __pad4;
! #else
! unsigned long __pad4;
! unsigned long st_blocks;
! #endif
! unsigned long __pad5;
! long int st_atime; /* Time of last access. */
! unsigned long __pad6;
! long int st_mtime; /* Time of last modification. */
! unsigned long __pad7;
! long int st_ctime; /* Time of last status change. */
! unsigned long __pad8;
! unsigned long long int st_ino; /* File serial number. */
};
|