Skip to content

Commit 63d7f9f

Browse files
committed
openrisc: Support storing and restoring fpu state
OpenRISC floating point state is not so expensive to save as OpenRISC uses general purpose registers for floating point instructions. We need to save only the floating point status and control register, FPCSR. Add support to maintain the FPCSR unconditionally upon exceptions and switches. On machines that do not support FPU this will always just store 0x0 and restore is a no-op. On FPU systems this adds an additional special purpose register read/write and read/write to memory (already cached). Signed-off-by: Stafford Horne <shorne@gmail.com>
1 parent 812489a commit 63d7f9f

3 files changed

Lines changed: 19 additions & 4 deletions

File tree

arch/openrisc/include/asm/ptrace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct pt_regs {
5959
* -1 for all other exceptions.
6060
*/
6161
long orig_gpr11; /* For restarting system calls */
62-
long dummy; /* Cheap alignment fix */
62+
long fpcsr; /* Floating point control status register. */
6363
long dummy2; /* Cheap alignment fix */
6464
};
6565

@@ -115,6 +115,6 @@ static inline long regs_return_value(struct pt_regs *regs)
115115
#define PT_GPR31 124
116116
#define PT_PC 128
117117
#define PT_ORIG_GPR11 132
118-
#define PT_SYSCALLNO 136
118+
#define PT_FPCSR 136
119119

120120
#endif /* __ASM_OPENRISC_PTRACE_H */

arch/openrisc/kernel/entry.S

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@
106106
l.mtspr r0,r3,SPR_EPCR_BASE ;\
107107
l.lwz r3,PT_SR(r1) ;\
108108
l.mtspr r0,r3,SPR_ESR_BASE ;\
109+
l.lwz r3,PT_FPCSR(r1) ;\
110+
l.mtspr r0,r3,SPR_FPCSR ;\
109111
l.lwz r2,PT_GPR2(r1) ;\
110112
l.lwz r3,PT_GPR3(r1) ;\
111113
l.lwz r4,PT_GPR4(r1) ;\
@@ -175,6 +177,8 @@ handler: ;\
175177
/* r30 already save */ ;\
176178
l.sw PT_GPR31(r1),r31 ;\
177179
TRACE_IRQS_OFF_ENTRY ;\
180+
l.mfspr r30,r0,SPR_FPCSR ;\
181+
l.sw PT_FPCSR(r1),r30 ;\
178182
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
179183
l.addi r30,r0,-1 ;\
180184
l.sw PT_ORIG_GPR11(r1),r30
@@ -215,6 +219,8 @@ handler: ;\
215219
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
216220
l.addi r30,r0,-1 ;\
217221
l.sw PT_ORIG_GPR11(r1),r30 ;\
222+
l.mfspr r30,r0,SPR_FPCSR ;\
223+
l.sw PT_FPCSR(r1),r30 ;\
218224
l.addi r3,r1,0 ;\
219225
/* r4 is exception EA */ ;\
220226
l.addi r5,r0,vector ;\
@@ -1087,6 +1093,10 @@ ENTRY(_switch)
10871093
l.sw PT_GPR28(r1),r28
10881094
l.sw PT_GPR30(r1),r30
10891095

1096+
/* Store the old FPU state to new pt_regs */
1097+
l.mfspr r29,r0,SPR_FPCSR
1098+
l.sw PT_FPCSR(r1),r29
1099+
10901100
l.addi r11,r10,0 /* Save old 'current' to 'last' return value*/
10911101

10921102
/* We use thread_info->ksp for storing the address of the above
@@ -1109,6 +1119,10 @@ ENTRY(_switch)
11091119
l.lwz r29,PT_SP(r1)
11101120
l.sw TI_KSP(r10),r29
11111121

1122+
/* Restore the old value of FPCSR */
1123+
l.lwz r29,PT_FPCSR(r1)
1124+
l.mtspr r0,r29,SPR_FPCSR
1125+
11121126
/* ...and restore the registers, except r11 because the return value
11131127
* has already been set above.
11141128
*/

arch/openrisc/kernel/traps.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ void show_registers(struct pt_regs *regs)
7575
in_kernel = 0;
7676

7777
printk("CPU #: %d\n"
78-
" PC: %08lx SR: %08lx SP: %08lx\n",
79-
smp_processor_id(), regs->pc, regs->sr, regs->sp);
78+
" PC: %08lx SR: %08lx SP: %08lx FPCSR: %08lx\n",
79+
smp_processor_id(), regs->pc, regs->sr, regs->sp,
80+
regs->fpcsr);
8081
printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
8182
0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
8283
printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",

0 commit comments

Comments
 (0)