]> err.no Git - linux-2.6/commitdiff
[XTENSA] Clean up elf-gregset.
authorChris Zankel <chris@zankel.net>
Tue, 12 Feb 2008 19:55:32 +0000 (11:55 -0800)
committerChris Zankel <chris@zankel.net>
Thu, 14 Feb 2008 01:09:08 +0000 (17:09 -0800)
Remove additional registers from the ELF gregset structure that
are only used by the kernel or are not required or invalid in
user-space. The ar registers are always aligned to a windowbase
value of 0, and the WB register is always assumed to be 0.
Increase the size of the structure to 128 entries. This will
provide enough space in future.

Signed-off-by: Chris Zankel <chris@zankel.net>
arch/xtensa/kernel/process.c
arch/xtensa/kernel/traps.c
include/asm-xtensa/elf.h

index f53d7bd9dfb208aa018536fefa7a42f2fc58e907..026138d641a41a29e04992641e3c380e164142ae 100644 (file)
@@ -194,51 +194,18 @@ unsigned long get_wchan(struct task_struct *p)
 void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
                   struct task_struct *tsk)
 {
-       int i, n, wb_offset;
-
-       elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
-       elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
-
-       __asm__ __volatile__ ("rsr  %0, 176\n" : "=a" (i));
-       elfregs->cpux = i;
-       __asm__ __volatile__ ("rsr  %0, 208\n" : "=a" (i));
-       elfregs->cpuy = i;
-
        /* Note:  PS.EXCM is not set while user task is running; its
         * being set in regs->ps is for exception handling convenience.
         */
 
        elfregs->pc             = regs->pc;
        elfregs->ps             = (regs->ps & ~(1 << PS_EXCM_BIT));
-       elfregs->exccause       = regs->exccause;
-       elfregs->excvaddr       = regs->excvaddr;
-       elfregs->windowbase     = regs->windowbase;
-       elfregs->windowstart    = regs->windowstart;
        elfregs->lbeg           = regs->lbeg;
        elfregs->lend           = regs->lend;
        elfregs->lcount         = regs->lcount;
        elfregs->sar            = regs->sar;
-       elfregs->syscall        = regs->syscall;
-
-       /* Copy register file.
-        * The layout looks like this:
-        *
-        * |  a0 ... a15  | Z ... Z |  arX ... arY  |
-        *  current window  unused    saved frames
-        */
-
-       memset (elfregs->ar, 0, sizeof(elfregs->ar));
-
-       wb_offset = regs->windowbase * 4;
-       n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
-
-       for (i = 0; i < n; i++)
-               elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
 
-       n = (regs->wmask >> 4) * 4;
-
-       for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
-               elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
+       memcpy (elfregs->a, regs->areg, sizeof(elfregs->a));
 }
 
 void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
@@ -252,40 +219,22 @@ void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
 void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
                      struct task_struct *tsk)
 {
-       int i, n, wb_offset;
+       const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
+       unsigned long ps;
 
        /* Note:  PS.EXCM is not set while user task is running; it
         * needs to be set in regs->ps is for exception handling convenience.
         */
 
+       ps = (regs->ps & ~ps_mask) | (elfregs->ps & ps_mask) | (1<<PS_EXCM_BIT);
+       regs->ps                = ps;
        regs->pc                = elfregs->pc;
-       regs->ps                = (elfregs->ps | (1 << PS_EXCM_BIT));
-       regs->exccause          = elfregs->exccause;
-       regs->excvaddr          = elfregs->excvaddr;
-       regs->windowbase        = elfregs->windowbase;
-       regs->windowstart       = elfregs->windowstart;
        regs->lbeg              = elfregs->lbeg;
        regs->lend              = elfregs->lend;
        regs->lcount            = elfregs->lcount;
        regs->sar               = elfregs->sar;
-       regs->syscall   = elfregs->syscall;
-
-       /* Clear everything. */
-
-       memset (regs->areg, 0, sizeof(regs->areg));
-
-       /* Copy regs from live window frame. */
-
-       wb_offset = regs->windowbase * 4;
-       n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
-
-       for (i = 0; i < n; i++)
-               regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
-
-       n = (regs->wmask >> 4) * 4;
 
-       for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
-               regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
+       memcpy (regs->areg, elfregs->a, sizeof(regs->areg));
 }
 
 /*
index 397bcd6ad08d4ca860e8d936862fd22f1f1629ac..6f722f91ba925f2dad1b33f63811ce2ba71c4a04 100644 (file)
@@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs)
 
        wmask = regs->wmask & ~1;
 
-       for (i = 0; i < 32; i++) {
-               if (wmask & (1 << (i / 4)))
-                       break;
+       for (i = 0; i < 16; i++) {
                if ((i % 8) == 0)
                        printk ("\n" KERN_INFO "a%02d: ", i);
                printk("%08lx ", regs->areg[i]);
index 467384542502640e21fb841e95b2b18cafdb55c1..0444507b438d89d0483a9b3cc3574f347f714717 100644 (file)
 
 /* ELF register definitions. This is needed for core dump support.  */
 
-/*
- * elf_gregset_t contains the application-level state in the following order:
- * Processor info:     config_version, cpuxy
- * Processor state:    pc, ps, exccause, excvaddr, wb, ws,
- *                     lbeg, lend, lcount, sar
- * GP regs:            ar0 - arXX
- */
-
 typedef unsigned long elf_greg_t;
 
 typedef struct {
-       elf_greg_t xchal_config_id0;
-       elf_greg_t xchal_config_id1;
-       elf_greg_t cpux;
-       elf_greg_t cpuy;
        elf_greg_t pc;
        elf_greg_t ps;
-       elf_greg_t exccause;
-       elf_greg_t excvaddr;
-       elf_greg_t windowbase;
-       elf_greg_t windowstart;
        elf_greg_t lbeg;
        elf_greg_t lend;
        elf_greg_t lcount;
        elf_greg_t sar;
-       elf_greg_t syscall;
-       elf_greg_t ar[64];
+       elf_greg_t windowstart;
+       elf_greg_t reserved[9+48];
+       elf_greg_t a[64];
 } xtensa_gregset_t;
 
 #define ELF_NGREG      (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
 
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
-/*
- *  Compute the size of the coprocessor and extra state layout (register info)
- *  table (in bytes).
- *  This is actually the maximum size of the table, as opposed to the size,
- *  which is available from the _xtensa_reginfo_table_size global variable.
- *
- *  (See also arch/xtensa/kernel/coprocessor.S)
- *
- */
-
-#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
-# define XTENSA_CPE_LTABLE_SIZE                0
-#else
-# define XTENSA_CPE_SEGMENT(num)       (num ? (1+num) : 0)
-# define XTENSA_CPE_LTABLE_ENTRIES     \
-               ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM)   \
-               + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM)   \
-               + 1             /* final entry */                       \
-               )
-# define XTENSA_CPE_LTABLE_SIZE                (XTENSA_CPE_LTABLE_ENTRIES * 8)
-#endif
-
-
-/*
- * Instantiations of the elf_fpregset_t type contain, in most
- * architectures, the floating point (FPU) register set.
- * For Xtensa, this type is extended to contain all custom state,
- * ie. coprocessor and "extra" (non-coprocessor) state (including,
- * for example, TIE-defined states and register files; as well
- * as other optional processor state).
- * This includes FPU state if a floating-point coprocessor happens
- * to have been configured within the Xtensa processor.
- *
- * TOTAL_FPREGS_SIZE is the required size (without rounding)
- * of elf_fpregset_t.  It provides space for the following:
- *
- *  a) 32-bit mask of active coprocessors for this task (similar
- *     to CPENABLE in single-threaded Xtensa processor systems)
- *
- *  b) table describing the layout of custom states (ie. of
- *      individual registers, etc) within the save areas
- *
- *  c)  save areas for each coprocessor and for non-coprocessor
- *      ("extra") state
- *
- * Note that save areas may require up to 16-byte alignment when
- * accessed by save/restore sequences.  We do not need to ensure
- * such alignment in an elf_fpregset_t structure because custom
- * state is not directly loaded/stored into it; rather, save area
- * contents are copied to elf_fpregset_t from the active save areas
- * (see 'struct task_struct' definition in processor.h for that)
- * using memcpy().  But we do allow space for such alignment,
- * to allow optimizations of layout and copying.
- */
-#if 0
-#define TOTAL_FPREGS_SIZE                                              \
-       (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
-#define ELF_NFPREG                                                     \
-       ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
-#else
-#define TOTAL_FPREGS_SIZE      0
-#define ELF_NFPREG             0
-#endif
+#define ELF_NFPREG     18
 
 typedef unsigned int elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];