aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/kernel
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 /arch/xtensa/kernel
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>
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r--arch/xtensa/kernel/process.c63
-rw-r--r--arch/xtensa/kernel/traps.c4
2 files changed, 7 insertions, 60 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]);