[xtensa-cvscommit] linux/arch/xtensa/kernel cptable.S,NONE,1.1 Makefile,1.3,1.4 handlers.S,1.10,1.11
Brought to you by:
zankel
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel
In directory sc8-pr-cvs1:/tmp/cvs-serv27017/arch/xtensa/kernel
Modified Files:
Makefile handlers.S process.c ptrace.c reset.c setup.c
signal.c traps.c
Added Files:
cptable.S
Log Message:
Implement TIE support in elf_fpregset_t for core dumps and ptrace.
The elf_fpregset_t contains coprocessor and non-coprocessor custom
state, as well as a table describing its layout for use by GDB.
Also add experimental traceback code on panic's (untested, but doesn't
break anything).
--- NEW FILE: cptable.S ---
/*
* arch/xtensa/kernel/cptable.S
*
* Xtensa processor configuration-specific table of coprocessor and
* other custom register layout information.
*
* 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) 2003 Tensilica Inc.
* Authors: Marc Gauthier <ma...@te...> <ma...@al...>
*/
/*
* This module contains a table that describes the layout of the various
* custom registers and states associated with each coprocessor, as well
* as those not associated with any coprocessor ("extra state").
* This table is included with core dumps and is available via the ptrace
* interface, allowing the layout of such register/state information to
* be modified in the kernel without affecting the debugger. Each
* register or state is identified using a 32-bit "libdb target number"
* assigned when the Xtensa processor is generated.
*/
#define _ASMLANGUAGE 1
#define _LANGUAGE_ASSEMBLY 1
#include <xtensa/config/core.h>
#include <linux/config.h>
/*
* The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
* describe the contents of coprocessor & extra save areas in terms of
* undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros. We define these
* latter macros here; they expand into a table of the format we want.
* The general format is:
*
* CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, bitmask, rsv2, rsv3)
* CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, bitmask, rsv2, rsv3)
* CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, numentries, contentsize,
* regname_base, regfile_name, rsv2, rsv3)
*
* For this table, we only care about the <libdbnum>, <offset> and <size> fields.
*/
/* Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below: */
#define CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, bitmask, rsv2, rsv3) \
reg_entry libdbnum, offset, size ;
#define CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, bitmask, rsv2, rsv3) \
reg_entry libdbnum, offset, size ;
#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, numentries, contentsize, \
regname_base, regfile_name, rsv2, rsv3) \
reg_entry libdbnum, offset, size ;
/* A single table entry: */
.macro reg_entry libdbnum, offset, size
.ifne (__last_offset-(__last_group_offset+\offset))
.word (0xFC000000+__last_offset-(__last_group_offset+\offset)) /* padding entry */
.endif
.word \libdbnum /* actual entry */
.set __last_offset, __last_group_offset+\offset+\size
.endm /* reg_entry */
/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
.macro reg_group cpnum, num_entries, alignment
.set __last_group_offset, (__last_offset + \alignment - 1) & -\alignment
.ifne \num_entries
.word 0xFD000000+(\cpnum<<16)+\num_entries
.endif
.endm /* reg_group */
/*
*
*/
.section .rodata, "a"
.globl _xtensa_reginfo_tables
.globl _xtensa_reginfo_table_size
.align 4
_xtensa_reginfo_table_size:
.word _xtensa_reginfo_table_end - _xtensa_reginfo_tables
_xtensa_reginfo_tables:
.set __last_offset, 0
reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
XCHAL_EXTRA_SA_CONTENTS_LIBDB
reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
XCHAL_CP0_SA_CONTENTS_LIBDB
reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
XCHAL_CP1_SA_CONTENTS_LIBDB
reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
XCHAL_CP2_SA_CONTENTS_LIBDB
reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
XCHAL_CP3_SA_CONTENTS_LIBDB
reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
XCHAL_CP4_SA_CONTENTS_LIBDB
reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
XCHAL_CP5_SA_CONTENTS_LIBDB
reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
XCHAL_CP6_SA_CONTENTS_LIBDB
reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
XCHAL_CP7_SA_CONTENTS_LIBDB
.word 0xFC000000 /* invalid register number, marks end of table */
_xtensa_reginfo_table_end:
Index: Makefile
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/Makefile,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Makefile 19 Oct 2002 04:39:53 -0000 1.3
--- Makefile 7 Feb 2003 02:03:35 -0000 1.4
***************
*** 15,19 ****
obj-y := entry.o handlers.o ioport.o ipc.o irq.o process.o ptrace.o \
reset.o semaphore.o setup.o signal.o sys.o syscall.o sysxtensa.o \
! traps.o vec_wexc.o vectors.o vm86.o xtensa_switch.o xtirq.o
# obj-$(CONFIG_BOOTSTRAP) += bootstrap.o
--- 15,20 ----
obj-y := entry.o handlers.o ioport.o ipc.o irq.o process.o ptrace.o \
reset.o semaphore.o setup.o signal.o sys.o syscall.o sysxtensa.o \
! traps.o vec_wexc.o vectors.o vm86.o xtensa_switch.o xtirq.o \
! cptable.o
# obj-$(CONFIG_BOOTSTRAP) += bootstrap.o
Index: handlers.S
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/handlers.S,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** handlers.S 30 Jan 2003 23:55:26 -0000 1.10
--- handlers.S 7 Feb 2003 02:03:35 -0000 1.11
***************
*** 957,961 ****
_GET_CURRENT a2
! addi a2, a2, THREAD_EXTRA // a2 <-- addr of save location
xchal_extra_store_funcbody
--- 957,961 ----
_GET_CURRENT a2
! addi a2, a2, THREAD_CPEXTRA // a2 <-- addr of save location
xchal_extra_store_funcbody
***************
*** 1354,1358 ****
_GET_CURRENT a2
! addi a2, a2, THREAD_EXTRA // a2 <-- addr of save location
xchal_extra_load_funcbody
--- 1354,1358 ----
_GET_CURRENT a2
! addi a2, a2, THREAD_CPEXTRA // a2 <-- addr of save location
xchal_extra_load_funcbody
***************
*** 1934,1938 ****
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION
/* First-level exit handler for unaligned exceptions.
--- 1934,1938 ----
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
/* First-level exit handler for unaligned exceptions.
***************
*** 2631,2635 ****
j unaligned_return
! #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION */
--- 2631,2635 ----
j unaligned_return
! #endif /* XCHAL_UNALIGNED_{LOAD,STORE}_EXCEPTION */
***************
*** 2884,2904 ****
! /* Only if coprocessors exist to we include handlers for Coprocessor
! * Disabled Exceptions. */
#if (XCHAL_CP_NUM)
- .data
- .align 4
-
- /* coproc_owners is an array of words, one per coprocessor. A zero
- * value indicates no user task owns the coprocessor. A nonzero value
- * indicates the opposite and is also the pointer to the top of the
- * task_struct (or TCB) for the owning task. */
-
- .global coproc_owners
- coproc_owners:
- .space 4*XCHAL_CP_MAX, 0
-
/* Allocate some scratch area in which to save original values of
* registers. Also define some offsets for robustness and
--- 2884,2892 ----
! /* Only if coprocessors exist do we include handlers for Coprocessor
! * Disabled Exceptions, for lazy coprocessor context switching. */
#if (XCHAL_CP_NUM)
/* Allocate some scratch area in which to save original values of
* registers. Also define some offsets for robustness and
***************
*** 2922,2925 ****
--- 2910,2915 ----
#define CP_SAVE_TOTAL (15*4)
+ .data
+ .align 4
cp_save_area:
.space CP_SAVE_TOTAL, 0
***************
*** 3097,3098 ****
--- 3087,3089 ----
#endif /* XCHAL_CP_NUM, or if at least one coproc exists */
+
Index: process.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/process.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** process.c 31 Jan 2003 04:37:19 -0000 1.7
--- process.c 7 Feb 2003 02:03:35 -0000 1.8
***************
*** 53,62 ****
}
! struct task_struct *last_task_used_math = NULL;
asmlinkage void ret_from_fork(void);
#if XCHAL_CP_NUM
- extern struct task_struct *coproc_owners[];
void release_all_cp (struct task_struct *tsk)
{
--- 53,66 ----
}
!
! /* Tasks that own contents of (last used) each coprocessor.
! * Entries are NULL (0) for unowned or non-existent coprocessors:
! */
! struct task_struct *coproc_owners[XCHAL_CP_MAX];
! struct task_struct *last_task_used_math = NULL; /* not used */
asmlinkage void ret_from_fork(void);
#if XCHAL_CP_NUM
void release_all_cp (struct task_struct *tsk)
{
***************
*** 110,145 ****
childregs->aregs[0] = 0; /* mark base of call stack */
} else {
childregs->aregs[1] = usp;
p->thread.current_ds = USER_DS;
! /* Zero through eight coprocessors may exist. Be sure
! * memory for saving state is setup properly. Note
! * that we assume kernel threads do not use
* coprocessors. */
! #if (XCHAL_CP_MASK & 1)
! p->thread.cpregs_ptr[0] = (unsigned) &p->thread.cp0_regs;
! #endif
! #if (XCHAL_CP_MASK & 2)
! p->thread.cpregs_ptr[1] = (unsigned) &p->thread.cp1_regs;
! #endif
! #if (XCHAL_CP_MASK & 4)
! p->thread.cpregs_ptr[2] = (unsigned) &p->thread.cp2_regs;
! #endif
! #if (XCHAL_CP_MASK & 8)
! p->thread.cpregs_ptr[3] = (unsigned) &p->thread.cp3_regs;
! #endif
! #if (XCHAL_CP_MASK & 16)
! p->thread.cpregs_ptr[4] = (unsigned) &p->thread.cp4_regs;
! #endif
! #if (XCHAL_CP_MASK & 32)
! p->thread.cpregs_ptr[5] = (unsigned) &p->thread.cp5_regs;
! #endif
! #if (XCHAL_CP_MASK & 64)
! p->thread.cpregs_ptr[6] = (unsigned) &p->thread.cp6_regs;
! #endif
! #if (XCHAL_CP_MASK & 128)
! p->thread.cpregs_ptr[7] = (unsigned) &p->thread.cp7_regs;
! #endif
}
--- 114,135 ----
childregs->aregs[0] = 0; /* mark base of call stack */
} else {
+ unsigned char *saptr; /* save area pointer */
+ int i;
+
childregs->aregs[1] = usp;
p->thread.current_ds = USER_DS;
! /* Up to eight coprocessors may exist. Be sure
! * memory for saving state is setup properly.
! * Note that we assume kernel threads do not use
* coprocessors. */
! saptr = p->thread.cpextra + XCHAL_EXTRA_SA_SIZE;
! for( i = 0; i < XCHAL_CP_MAX; i++ ) {
! saptr = (unsigned char*)( ((unsigned)saptr + Xthal_cpregs_align[i] - 1)
! & -Xthal_cpregs_align[i] );
! p->thread.cpregs_ptr[i] = saptr;
! saptr += Xthal_cpregs_size[i];
! }
}
***************
*** 150,234 ****
}
- /* Fill in the CP structure for a core dump. This includes any FPU
- * coprocessor. Here, we dump all coprocessors. */
- int dump_fpu(struct pt_regs *regs, struct user_cp *r)
- {
- #if XCHAL_HAVE_CP
- int retval = 0;
- struct task_struct *tsk = current;
-
- #if (XCHAL_CP_MASK & 1) && XCHAL_CP0_SA_SIZE
- memcpy(r, tsk->thread.cp0_regs, XCHAL_CP0_SA_SIZE);
- r += XCHAL_CP0_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 2) && XCHAL_CP1_SA_SIZE
- memcpy(r, tsk->thread.cp1_regs, XCHAL_CP1_SA_SIZE);
- r += XCHAL_CP1_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 4) && XCHAL_CP2_SA_SIZE
- memcpy(r, tsk->thread.cp2_regs, XCHAL_CP2_SA_SIZE);
- r += XCHAL_CP2_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 8) && XCHAL_CP3_SA_SIZE
- memcpy(r, tsk->thread.cp3_regs, XCHAL_CP3_SA_SIZE);
- r += XCHAL_CP3_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 16) && XCHAL_CP4_SA_SIZE
- memcpy(r, tsk->thread.cp4_regs, XCHAL_CP4_SA_SIZE);
- r += XCHAL_CP4_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 32) && XCHAL_CP5_SA_SIZE
- memcpy(r, tsk->thread.cp5_regs, XCHAL_CP5_SA_SIZE);
- r += XCHAL_CP5_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 64) && XCHAL_CP6_SA_SIZE
- memcpy(r, tsk->thread.cp6_regs, XCHAL_CP6_SA_SIZE);
- r += XCHAL_CP6_SA_SIZE;
- retval = 1;
- #endif
-
- #if (XCHAL_CP_MASK & 128) && XCHAL_CP7_SA_SIZE
- memcpy(r, tsk->thread.cp7_regs, XCHAL_CP7_SA_SIZE);
- r += XCHAL_CP7_SA_SIZE;
- retval = 1;
- #endif
-
- return retval;
-
- #endif /* if XCHAL_HAVE_CP */
-
- return 0; /* no coprocessors on this processor */
- }
-
-
- /* Fill in the user structure for a core dump.. */
- void dump_thread(struct pt_regs * regs, struct user * dump)
- {
- dump->magic = CMAGIC;
- dump->start_code = current->mm->start_code;
- dump->start_data = current->mm->start_data;
- dump->start_stack = regs->aregs[1] & ~(PAGE_SIZE - 1);
- dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
- dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
- dump->u_ssize = (current->mm->start_stack - dump->start_stack +
- PAGE_SIZE - 1) >> PAGE_SHIFT;
- /* XTFIXME?: Debug registers will come here. */
-
- dump->regs = *regs;
-
- dump->u_fpvalid = dump_fpu(regs, &dump->cps);
- }
/*
--- 140,143 ----
***************
*** 432,433 ****
--- 341,456 ----
}
}
+
+ /* do_save_fpregs() gathers information from 'struct pt_regs' and
+ * 'current->thread' to fill in the elf_fpregset_t structure.
+ *
+ * Core files and ptrace use elf_fpregset_t. */
+
+ void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, struct task_struct *tsk)
+ {
+ extern unsigned char _xtensa_reginfo_tables[];
+ extern unsigned _xtensa_reginfo_table_size;
+ int i;
+
+ /*
+ * Before dumping coprocessor state from memory,
+ * ensure any live coprocessor contents for this
+ * task are first saved to memory:
+ */
+ for (i = 0; i < XCHAL_CP_MAX; i++) {
+ if (tsk == coproc_owners[i]) {
+ xthal_save_cpregs( tsk->thread.cpregs_ptr[i], i );
+ coproc_owners[i] = 0;
+ xthal_invalidate_cp( i );
+ }
+ }
+
+ /* Now dump coprocessor & extra state: */
+ memcpy((unsigned char*)fpregs,
+ _xtensa_reginfo_tables, _xtensa_reginfo_table_size);
+ memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
+ tsk->thread.cpextra, TOTAL_CPEXTRA_SIZE);
+ }
+
+ /* The inverse of do_save_fpregs().
+ * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
+ * Returns 0 on success, non-zero if layout doesn't match. */
+
+ int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, struct task_struct *tsk)
+ {
+ extern unsigned char _xtensa_reginfo_tables[];
+ extern unsigned _xtensa_reginfo_table_size;
+ int i;
+
+ /* Make sure save area layouts match.
+ * XTFIXME: in the future we could allow restoring from
+ * a different layout of the same registers, by comparing
+ * fpregs' table with _xtensa_reginfo_tables and matching
+ * entries and copying registers one at a time.
+ * Not too sure yet whether that's very useful.
+ */
+ if( memcmp((unsigned char*)fpregs,
+ _xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
+ return -1;
+ }
+
+ /*
+ * Before restoring coprocessor state from memory,
+ * ensure any live coprocessor contents for this
+ * task are first invalidated.
+ */
+ for (i = 0; i < XCHAL_CP_MAX; i++) {
+ if (tsk == coproc_owners[i]) {
+ /*xthal_save_cpregs( tsk->thread.cpregs_ptr[i], i );*/
+ coproc_owners[i] = 0;
+ xthal_invalidate_cp( i );
+ }
+ }
+
+ /* Now restore coprocessor & extra state: */
+ memcpy(tsk->thread.cpextra,
+ (unsigned char*)fpregs + _xtensa_reginfo_table_size,
+ TOTAL_CPEXTRA_SIZE);
+ return 0;
+ }
+
+ /*
+ * Fill in the CP structure for a core dump.
+ * This includes any FPU coprocessor.
+ * Here, we dump all coprocessors, and other ("extra") custom state.
+ *
+ * This function is called by elf_core_dump() in fs/binfmt_elf.c
+ * (in which case 'regs' comes from calls to do_coredump, see signals.c).
+ */
+ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+ {
+ #if TOTAL_CPEXTRA_SIZE > 16 /* see asm/cpextra.h for this magic number 16 */
+ do_save_fpregs (r, regs, current); /* XTFIXME: will regs always be for current? */
+
+ /* For now, bit 16 means some extra state may be present: */
+ return 0x10000 | XCHAL_CP_MASK; /* XTFIXME!! need to track to return more accurate mask */
+ #else
+ return 0; /* no coprocessors active on this processor */
+ #endif
+ }
+
+
+ #if 0 /* not used -- only for a.out formats... */
+ /* Fill in the user structure for a core dump.. */
+ void dump_thread(struct pt_regs * regs, struct user * dump)
+ {
+ dump->magic = CMAGIC;
+ dump->start_code = current->mm->start_code;
+ dump->start_data = current->mm->start_data;
+ dump->start_stack = regs->aregs[1] & ~(PAGE_SIZE - 1);
+ dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
+ dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
+ dump->u_ssize = (current->mm->start_stack - dump->start_stack +
+ PAGE_SIZE - 1) >> PAGE_SHIFT;
+ /* XTFIXME?: Debug registers will come here. */
+
+ dump->regs = *regs;
+
+ dump->u_cpevalid = dump_fpu(regs, &dump->cpregs);
+ }
+ #endif /*0*/
Index: ptrace.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/ptrace.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** ptrace.c 29 Jan 2003 06:18:00 -0000 1.7
--- ptrace.c 7 Feb 2003 02:03:35 -0000 1.8
***************
*** 10,15 ****
* Kevin D. Kissell, ke...@mi... and Carsten Langgaard, car...@mi...
* Copyright (C) 1999 MIPS Technologies, Inc.
! * Scott Foehner <sfo...@ya...> and Joe Taylor <jo...@te...>
! * Copyright (C) 2002 Tensilica, Inc.
*/
#include <linux/config.h>
--- 10,17 ----
* Kevin D. Kissell, ke...@mi... and Carsten Langgaard, car...@mi...
* Copyright (C) 1999 MIPS Technologies, Inc.
! * Scott Foehner <sfo...@ya...>,
! * Joe Taylor <jo...@te...>, and
! * Marc Gauthier <ma...@te...> <ma...@al...>
! * Copyright (C) 2002 - 2003 Tensilica, Inc.
*/
#include <linux/config.h>
***************
*** 33,36 ****
--- 35,40 ----
extern void do_copy_regs (elf_gregset_t *, struct pt_regs *, struct task_struct *);
extern void do_restore_regs (elf_gregset_t *, struct pt_regs *, struct task_struct *);
+ extern void do_save_fpregs (elf_fpregset_t *, struct pt_regs *, struct task_struct *);
+ extern int do_restore_fpregs (elf_fpregset_t *, struct pt_regs *, struct task_struct *);
***************
*** 76,80 ****
struct task_struct *child;
int res;
! extern void save_fp(struct task_struct *);
lock_kernel();
--- 80,84 ----
struct task_struct *child;
int res;
! /*extern void save_fp(struct task_struct *);*/
lock_kernel();
***************
*** 390,396 ****
--- 394,435 ----
case PTRACE_GETFPREGS:
+ {
+ /* 'data' points to user memory in which to write.
+ * For convenience, we use the handy
+ * elf_fpregset_t format. */
+
+ elf_fpregset_t fpregs;
+ struct pt_regs *regs = __KSTK_TOS(child);
+
+ do_save_fpregs (&fpregs, regs, child);
+
+ /* Now, copy to user space nice and easy... */
+ res = 0;
+ if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
+ res = -EFAULT;
break;
+ }
case PTRACE_SETFPREGS:
+ {
+ /* 'data' points to user memory that contains the new
+ * values in the elf_fpregset_t format. */
+
+ elf_fpregset_t fpregs;
+ struct pt_regs *regs = __KSTK_TOS(child);
+
+ if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
+ res = -EFAULT;
+ break;
+ }
+
+ if (do_restore_fpregs (&fpregs, regs, child))
+ res = -EIO;
+ break;
+ }
+
+ case PTRACE_GETFPREGSIZE:
+ /* 'data' points to 'unsigned long' set to the size of elf_fpregset_t */
+ res = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
break;
Index: reset.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/reset.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** reset.c 18 Oct 2002 21:57:27 -0000 1.2
--- reset.c 7 Feb 2003 02:03:35 -0000 1.3
***************
*** 3,6 ****
--- 3,8 ----
*
* Reset the machine.
+ *
+ * Copyright (C) 2003 Tensilica Inc.
*/
#include <linux/kernel.h>
Index: setup.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/setup.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** setup.c 29 Jan 2003 06:18:00 -0000 1.4
--- setup.c 7 Feb 2003 02:03:35 -0000 1.5
***************
*** 5,9 ****
*
* Copyright (C) 1995 Linus Torvalds
! * Copyright (C) 2001 - 2002 Tensilica Inc.
* Author(s): Chris Zankel <za...@te...> <ch...@za...>
* Joe Taylor <jo...@te..., jo...@ya...>
--- 5,9 ----
*
* Copyright (C) 1995 Linus Torvalds
! * Copyright (C) 2001 - 2003 Tensilica Inc.
* Author(s): Chris Zankel <za...@te...> <ch...@za...>
* Joe Taylor <jo...@te..., jo...@ya...>
***************
*** 18,21 ****
--- 18,23 ----
#include <linux/tty.h>
#include <linux/bootmem.h>
+ #include <linux/kernel.h>
+ #include <linux/notifier.h>
#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
#include <linux/console.h>
***************
*** 236,239 ****
--- 238,277 ----
*/
+ #define DEBUG_PANIC_TRACEBACK
+ #ifdef DEBUG_PANIC_TRACEBACK
+ /* Panic handler -- display task traceback */
+ static int xtensa_panic_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+ {
+ #define MAX_TRACEBACK 100
+ register unsigned current_retpc asm ("a0"); /* return address */
+ register unsigned *current_sp asm ("a1"); /* current stack pointer */
+ unsigned retpc, next_retpc, *sp;
+ int i;
+
+ printk( "Call traceback:\n" );
+ xthal_window_spill(); /* save any live caller windows to stack */
+ sp = current_sp; /* start with current stack frame */
+ retpc = current_retpc; /* and current return address */
+ for( i = 0; i < MAX_TRACEBACK; i++ ) {
+ next_retpc = sp[-4]; /* a0 of caller */
+ sp = (unsigned*) sp[-3]; /* a1 of caller -- go to next caller */
+ if( retpc == 0 || sp == 0 ) { /* end of call stack? */
+ printk( " (end of traceback)\n" );
+ break;
+ }
+ printk( " SP=%08X PC=%08X\n", (unsigned) sp, retpc );
+ retpc = next_retpc;
+ }
+ return NOTIFY_DONE;
+ }
+
+ static struct notifier_block xtensa_panic_block = {
+ xtensa_panic_event,
+ NULL,
+ 0
+ };
+ #endif /* DEBUG_PANIC_TRACEBACK */
+
extern char _end;
***************
*** 300,303 ****
--- 338,346 ----
conswitchp = &dummy_con;
# endif
+ #endif
+
+ #ifdef DEBUG_PANIC_TRACEBACK
+ /* Register panic handler, for debugging purposes only: */
+ notifier_chain_register(&panic_notifier_list, &xtensa_panic_block);
#endif
}
Index: signal.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/signal.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** signal.c 8 Nov 2002 01:10:18 -0000 1.2
--- signal.c 7 Feb 2003 02:03:35 -0000 1.3
***************
*** 250,254 ****
}
#if (XCHAL_EXTRA_SA_SIZE > 0)
! err |= __copy_from_user(thread->extra,sc->sc_extra,XCHAL_EXTRA_SA_SIZE);
#endif /* (XCHAL_EXTRA_SA_SIZE > 0) */
--- 250,254 ----
}
#if (XCHAL_EXTRA_SA_SIZE > 0)
! err |= __copy_from_user(thread->cpextra,sc->sc_extra,XCHAL_EXTRA_SA_SIZE);
#endif /* (XCHAL_EXTRA_SA_SIZE > 0) */
***************
*** 304,308 ****
}
#if (XCHAL_EXTRA_SA_SIZE > 0)
! err |= __copy_to_user(sc->sc_extra, thread->extra, XCHAL_EXTRA_SA_SIZE);
#endif /* (XCHAL_EXTRA_SA_SIZE > 0) */
--- 304,308 ----
}
#if (XCHAL_EXTRA_SA_SIZE > 0)
! err |= __copy_to_user(sc->sc_extra, thread->cpextra, XCHAL_EXTRA_SA_SIZE);
#endif /* (XCHAL_EXTRA_SA_SIZE > 0) */
Index: traps.c
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/traps.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** traps.c 29 Jan 2003 06:18:00 -0000 1.6
--- traps.c 7 Feb 2003 02:03:35 -0000 1.7
***************
*** 257,261 ****
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION
static void
handle_unaligned_user (struct pt_regs *regs)
--- 257,261 ----
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
static void
handle_unaligned_user (struct pt_regs *regs)
***************
*** 415,421 ****
}
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION
! set_except_vector(EXC_CODE_KERNEL + XCHAL_EXCCAUSE_LOAD_STORE_ALIGNMENT, handle_unaligned_kernel);
! set_c_except_handler (XCHAL_EXCCAUSE_LOAD_STORE_ALIGNMENT, handle_unaligned_user);
#endif
--- 415,421 ----
}
! #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
! /*set_except_vector(EXC_CODE_KERNEL + XCHAL_EXCCAUSE_UNALIGNED, handle_unaligned_kernel);*/ /*XTFIXME - turned off for debugging*/
! set_c_except_handler (XCHAL_EXCCAUSE_UNALIGNED, handle_unaligned_user);
#endif
***************
*** 528,535 ****
"a6: %08x a14: %08x\n"
"a7: %08x a15: %08x\n",
! regs->aregs[0], regs->aregs[1], regs->aregs[2], regs->aregs[3],
! regs->aregs[4], regs->aregs[5], regs->aregs[6], regs->aregs[7],
! regs->aregs[8], regs->aregs[9], regs->aregs[10],regs->aregs[11],
! regs->aregs[12],regs->aregs[13],regs->aregs[14],regs->aregs[15] );
/*
--- 528,539 ----
"a6: %08x a14: %08x\n"
"a7: %08x a15: %08x\n",
! regs->aregs[0], regs->aregs[8],
! regs->aregs[1], regs->aregs[9],
! regs->aregs[2], regs->aregs[10],
! regs->aregs[3], regs->aregs[11],
! regs->aregs[4], regs->aregs[12],
! regs->aregs[5], regs->aregs[13],
! regs->aregs[6], regs->aregs[14],
! regs->aregs[7], regs->aregs[15] );
/*
|