Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 85930
b: refs/heads/master
c: 8d7e824
h: refs/heads/master
v: v3
  • Loading branch information
Chris Zankel committed Feb 14, 2008
1 parent 2d2e167 commit 40cd93e
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 149 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0b2c3afdaaaa3e577300b2235df43eb8af00020b
refs/heads/master: 8d7e8240e66cecc84a375aceb26942d02b291198
63 changes: 6 additions & 57 deletions trunk/arch/xtensa/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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));
}

/*
Expand Down
4 changes: 1 addition & 3 deletions trunk/arch/xtensa/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
92 changes: 4 additions & 88 deletions trunk/include/asm-xtensa/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,109 +72,25 @@

/* 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];
Expand Down

0 comments on commit 40cd93e

Please sign in to comment.