diff options
author | Chris Zankel <chris@zankel.net> | 2008-02-12 14:55:32 -0500 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2008-02-13 20:09:08 -0500 |
commit | 8d7e8240e66cecc84a375aceb26942d02b291198 (patch) | |
tree | 97074169ed7a281ccf5207a653781f57ddb2bffc /arch/xtensa | |
parent | 0b2c3afdaaaa3e577300b2235df43eb8af00020b (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')
-rw-r--r-- | arch/xtensa/kernel/process.c | 63 | ||||
-rw-r--r-- | arch/xtensa/kernel/traps.c | 4 |
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) | |||
194 | void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, | 194 | void 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 | ||
244 | void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) | 211 | 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) | |||
252 | void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, | 219 | void 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]); |