aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2008-02-12 14:55:32 -0500
committerChris Zankel <chris@zankel.net>2008-02-13 20:09:08 -0500
commit8d7e8240e66cecc84a375aceb26942d02b291198 (patch)
tree97074169ed7a281ccf5207a653781f57ddb2bffc
parent0b2c3afdaaaa3e577300b2235df43eb8af00020b (diff)
[XTENSA] Clean up elf-gregset.
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>
-rw-r--r--arch/xtensa/kernel/process.c63
-rw-r--r--arch/xtensa/kernel/traps.c4
-rw-r--r--include/asm-xtensa/elf.h92
3 files changed, 11 insertions, 148 deletions
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index f53d7bd9dfb2..026138d641a4 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -194,51 +194,18 @@ unsigned long get_wchan(struct task_struct *p)
194void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, 194void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
195 struct task_struct *tsk) 195 struct task_struct *tsk)
196{ 196{
197 int i, n, wb_offset;
198
199 elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
200 elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
201
202 __asm__ __volatile__ ("rsr %0, 176\n" : "=a" (i));
203 elfregs->cpux = i;
204 __asm__ __volatile__ ("rsr %0, 208\n" : "=a" (i));
205 elfregs->cpuy = i;
206
207 /* Note: PS.EXCM is not set while user task is running; its 197 /* Note: PS.EXCM is not set while user task is running; its
208 * being set in regs->ps is for exception handling convenience. 198 * being set in regs->ps is for exception handling convenience.
209 */ 199 */
210 200
211 elfregs->pc = regs->pc; 201 elfregs->pc = regs->pc;
212 elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); 202 elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT));
213 elfregs->exccause = regs->exccause;
214 elfregs->excvaddr = regs->excvaddr;
215 elfregs->windowbase = regs->windowbase;
216 elfregs->windowstart = regs->windowstart;
217 elfregs->lbeg = regs->lbeg; 203 elfregs->lbeg = regs->lbeg;
218 elfregs->lend = regs->lend; 204 elfregs->lend = regs->lend;
219 elfregs->lcount = regs->lcount; 205 elfregs->lcount = regs->lcount;
220 elfregs->sar = regs->sar; 206 elfregs->sar = regs->sar;
221 elfregs->syscall = regs->syscall;
222
223 /* Copy register file.
224 * The layout looks like this:
225 *
226 * | a0 ... a15 | Z ... Z | arX ... arY |
227 * current window unused saved frames
228 */
229
230 memset (elfregs->ar, 0, sizeof(elfregs->ar));
231
232 wb_offset = regs->windowbase * 4;
233 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
234
235 for (i = 0; i < n; i++)
236 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
237 207
238 n = (regs->wmask >> 4) * 4; 208 memcpy (elfregs->a, regs->areg, sizeof(elfregs->a));
239
240 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
241 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
242} 209}
243 210
244void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) 211void 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)
252void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, 219void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
253 struct task_struct *tsk) 220 struct task_struct *tsk)
254{ 221{
255 int i, n, wb_offset; 222 const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
223 unsigned long ps;
256 224
257 /* Note: PS.EXCM is not set while user task is running; it 225 /* Note: PS.EXCM is not set while user task is running; it
258 * needs to be set in regs->ps is for exception handling convenience. 226 * needs to be set in regs->ps is for exception handling convenience.
259 */ 227 */
260 228
229 ps = (regs->ps & ~ps_mask) | (elfregs->ps & ps_mask) | (1<<PS_EXCM_BIT);
230 regs->ps = ps;
261 regs->pc = elfregs->pc; 231 regs->pc = elfregs->pc;
262 regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT));
263 regs->exccause = elfregs->exccause;
264 regs->excvaddr = elfregs->excvaddr;
265 regs->windowbase = elfregs->windowbase;
266 regs->windowstart = elfregs->windowstart;
267 regs->lbeg = elfregs->lbeg; 232 regs->lbeg = elfregs->lbeg;
268 regs->lend = elfregs->lend; 233 regs->lend = elfregs->lend;
269 regs->lcount = elfregs->lcount; 234 regs->lcount = elfregs->lcount;
270 regs->sar = elfregs->sar; 235 regs->sar = elfregs->sar;
271 regs->syscall = elfregs->syscall;
272
273 /* Clear everything. */
274
275 memset (regs->areg, 0, sizeof(regs->areg));
276
277 /* Copy regs from live window frame. */
278
279 wb_offset = regs->windowbase * 4;
280 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
281
282 for (i = 0; i < n; i++)
283 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
284
285 n = (regs->wmask >> 4) * 4;
286 236
287 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--) 237 memcpy (regs->areg, elfregs->a, sizeof(regs->areg));
288 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
289} 238}
290 239
291/* 240/*
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 397bcd6ad08d..6f722f91ba92 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs)
349 349
350 wmask = regs->wmask & ~1; 350 wmask = regs->wmask & ~1;
351 351
352 for (i = 0; i < 32; i++) { 352 for (i = 0; i < 16; i++) {
353 if (wmask & (1 << (i / 4)))
354 break;
355 if ((i % 8) == 0) 353 if ((i % 8) == 0)
356 printk ("\n" KERN_INFO "a%02d: ", i); 354 printk ("\n" KERN_INFO "a%02d: ", i);
357 printk("%08lx ", regs->areg[i]); 355 printk("%08lx ", regs->areg[i]);
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 467384542502..0444507b438d 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -72,109 +72,25 @@
72 72
73/* ELF register definitions. This is needed for core dump support. */ 73/* ELF register definitions. This is needed for core dump support. */
74 74
75/*
76 * elf_gregset_t contains the application-level state in the following order:
77 * Processor info: config_version, cpuxy
78 * Processor state: pc, ps, exccause, excvaddr, wb, ws,
79 * lbeg, lend, lcount, sar
80 * GP regs: ar0 - arXX
81 */
82
83typedef unsigned long elf_greg_t; 75typedef unsigned long elf_greg_t;
84 76
85typedef struct { 77typedef struct {
86 elf_greg_t xchal_config_id0;
87 elf_greg_t xchal_config_id1;
88 elf_greg_t cpux;
89 elf_greg_t cpuy;
90 elf_greg_t pc; 78 elf_greg_t pc;
91 elf_greg_t ps; 79 elf_greg_t ps;
92 elf_greg_t exccause;
93 elf_greg_t excvaddr;
94 elf_greg_t windowbase;
95 elf_greg_t windowstart;
96 elf_greg_t lbeg; 80 elf_greg_t lbeg;
97 elf_greg_t lend; 81 elf_greg_t lend;
98 elf_greg_t lcount; 82 elf_greg_t lcount;
99 elf_greg_t sar; 83 elf_greg_t sar;
100 elf_greg_t syscall; 84 elf_greg_t windowstart;
101 elf_greg_t ar[64]; 85 elf_greg_t reserved[9+48];
86 elf_greg_t a[64];
102} xtensa_gregset_t; 87} xtensa_gregset_t;
103 88
104#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t)) 89#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
105 90
106typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 91typedef elf_greg_t elf_gregset_t[ELF_NGREG];
107 92
108/* 93#define ELF_NFPREG 18
109 * Compute the size of the coprocessor and extra state layout (register info)
110 * table (in bytes).
111 * This is actually the maximum size of the table, as opposed to the size,
112 * which is available from the _xtensa_reginfo_table_size global variable.
113 *
114 * (See also arch/xtensa/kernel/coprocessor.S)
115 *
116 */
117
118#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
119# define XTENSA_CPE_LTABLE_SIZE 0
120#else
121# define XTENSA_CPE_SEGMENT(num) (num ? (1+num) : 0)
122# define XTENSA_CPE_LTABLE_ENTRIES \
123 ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
124 + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM) \
125 + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM) \
126 + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM) \
127 + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM) \
128 + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM) \
129 + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM) \
130 + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM) \
131 + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM) \
132 + 1 /* final entry */ \
133 )
134# define XTENSA_CPE_LTABLE_SIZE (XTENSA_CPE_LTABLE_ENTRIES * 8)
135#endif
136
137
138/*
139 * Instantiations of the elf_fpregset_t type contain, in most
140 * architectures, the floating point (FPU) register set.
141 * For Xtensa, this type is extended to contain all custom state,
142 * ie. coprocessor and "extra" (non-coprocessor) state (including,
143 * for example, TIE-defined states and register files; as well
144 * as other optional processor state).
145 * This includes FPU state if a floating-point coprocessor happens
146 * to have been configured within the Xtensa processor.
147 *
148 * TOTAL_FPREGS_SIZE is the required size (without rounding)
149 * of elf_fpregset_t. It provides space for the following:
150 *
151 * a) 32-bit mask of active coprocessors for this task (similar
152 * to CPENABLE in single-threaded Xtensa processor systems)
153 *
154 * b) table describing the layout of custom states (ie. of
155 * individual registers, etc) within the save areas
156 *
157 * c) save areas for each coprocessor and for non-coprocessor
158 * ("extra") state
159 *
160 * Note that save areas may require up to 16-byte alignment when
161 * accessed by save/restore sequences. We do not need to ensure
162 * such alignment in an elf_fpregset_t structure because custom
163 * state is not directly loaded/stored into it; rather, save area
164 * contents are copied to elf_fpregset_t from the active save areas
165 * (see 'struct task_struct' definition in processor.h for that)
166 * using memcpy(). But we do allow space for such alignment,
167 * to allow optimizations of layout and copying.
168 */
169#if 0
170#define TOTAL_FPREGS_SIZE \
171 (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
172#define ELF_NFPREG \
173 ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
174#else
175#define TOTAL_FPREGS_SIZE 0
176#define ELF_NFPREG 0
177#endif
178 94
179typedef unsigned int elf_fpreg_t; 95typedef unsigned int elf_fpreg_t;
180typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 96typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];