Skip to content

Commit 5901037

Browse files
committed
Merge tag 'for-linus' of https://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne: "A few cleanups and fixups from me: - Add a few missing relocations to fix module loading - Cleanup FPU state save and restore to be more efficient - Cleanups to traps handling and logging - Fix issue with poweroff being broken after recent power driver refactorings" * tag 'for-linus' of https://github.com/openrisc/linux: openrisc: Move FPU state out of pt_regs openrisc: Add FPU config openrisc: traps: Don't send signals to kernel mode threads openrisc: traps: Remove calls to show_registers before die openrisc: traps: Convert printks to pr_<level> macros openrisc: Add support for more module relocations openrisc: Define openrisc relocation types openrisc: Use do_kernel_power_off()
2 parents c59cebe + 4dc70e1 commit 5901037

File tree

11 files changed

+243
-111
lines changed

11 files changed

+243
-111
lines changed

arch/openrisc/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,15 @@ config SMP
188188

189189
If you don't know what to do here, say N.
190190

191+
config FPU
192+
bool "FPU support"
193+
default y
194+
help
195+
Say N here if you want to disable all floating-point related procedures
196+
in the kernel and reduce binary size.
197+
198+
If you don't know what to do here, say Y.
199+
191200
source "kernel/Kconfig.hz"
192201

193202
config OPENRISC_NO_SPR_SR_DSX

arch/openrisc/include/asm/fpu.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __ASM_OPENRISC_FPU_H
3+
#define __ASM_OPENRISC_FPU_H
4+
5+
struct task_struct;
6+
7+
#ifdef CONFIG_FPU
8+
static inline void save_fpu(struct task_struct *task)
9+
{
10+
task->thread.fpcsr = mfspr(SPR_FPCSR);
11+
}
12+
13+
static inline void restore_fpu(struct task_struct *task)
14+
{
15+
mtspr(SPR_FPCSR, task->thread.fpcsr);
16+
}
17+
#else
18+
#define save_fpu(tsk) do { } while (0)
19+
#define restore_fpu(tsk) do { } while (0)
20+
#endif
21+
22+
#endif /* __ASM_OPENRISC_FPU_H */

arch/openrisc/include/asm/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
struct task_struct;
4545

4646
struct thread_struct {
47+
long fpcsr; /* Floating point control status register. */
4748
};
4849

4950
/*

arch/openrisc/include/asm/ptrace.h

Lines changed: 1 addition & 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 fpcsr; /* Floating point control status register. */
62+
long dummy; /* Cheap alignment fix */
6363
long dummy2; /* Cheap alignment fix */
6464
};
6565

@@ -115,6 +115,5 @@ 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_FPCSR 136
119118

120119
#endif /* __ASM_OPENRISC_PTRACE_H */

arch/openrisc/include/uapi/asm/elf.h

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,72 @@
3434
#include <asm/ptrace.h>
3535

3636
/* The OR1K relocation types... not all relevant for module loader */
37-
#define R_OR32_NONE 0
38-
#define R_OR32_32 1
39-
#define R_OR32_16 2
40-
#define R_OR32_8 3
41-
#define R_OR32_CONST 4
42-
#define R_OR32_CONSTH 5
43-
#define R_OR32_JUMPTARG 6
44-
#define R_OR32_VTINHERIT 7
45-
#define R_OR32_VTENTRY 8
37+
#define R_OR1K_NONE 0
38+
#define R_OR1K_32 1
39+
#define R_OR1K_16 2
40+
#define R_OR1K_8 3
41+
#define R_OR1K_LO_16_IN_INSN 4
42+
#define R_OR1K_HI_16_IN_INSN 5
43+
#define R_OR1K_INSN_REL_26 6
44+
#define R_OR1K_GNU_VTENTRY 7
45+
#define R_OR1K_GNU_VTINHERIT 8
46+
#define R_OR1K_32_PCREL 9
47+
#define R_OR1K_16_PCREL 10
48+
#define R_OR1K_8_PCREL 11
49+
#define R_OR1K_GOTPC_HI16 12
50+
#define R_OR1K_GOTPC_LO16 13
51+
#define R_OR1K_GOT16 14
52+
#define R_OR1K_PLT26 15
53+
#define R_OR1K_GOTOFF_HI16 16
54+
#define R_OR1K_GOTOFF_LO16 17
55+
#define R_OR1K_COPY 18
56+
#define R_OR1K_GLOB_DAT 19
57+
#define R_OR1K_JMP_SLOT 20
58+
#define R_OR1K_RELATIVE 21
59+
#define R_OR1K_TLS_GD_HI16 22
60+
#define R_OR1K_TLS_GD_LO16 23
61+
#define R_OR1K_TLS_LDM_HI16 24
62+
#define R_OR1K_TLS_LDM_LO16 25
63+
#define R_OR1K_TLS_LDO_HI16 26
64+
#define R_OR1K_TLS_LDO_LO16 27
65+
#define R_OR1K_TLS_IE_HI16 28
66+
#define R_OR1K_TLS_IE_LO16 29
67+
#define R_OR1K_TLS_LE_HI16 30
68+
#define R_OR1K_TLS_LE_LO16 31
69+
#define R_OR1K_TLS_TPOFF 32
70+
#define R_OR1K_TLS_DTPOFF 33
71+
#define R_OR1K_TLS_DTPMOD 34
72+
#define R_OR1K_AHI16 35
73+
#define R_OR1K_GOTOFF_AHI16 36
74+
#define R_OR1K_TLS_IE_AHI16 37
75+
#define R_OR1K_TLS_LE_AHI16 38
76+
#define R_OR1K_SLO16 39
77+
#define R_OR1K_GOTOFF_SLO16 40
78+
#define R_OR1K_TLS_LE_SLO16 41
79+
#define R_OR1K_PCREL_PG21 42
80+
#define R_OR1K_GOT_PG21 43
81+
#define R_OR1K_TLS_GD_PG21 44
82+
#define R_OR1K_TLS_LDM_PG21 45
83+
#define R_OR1K_TLS_IE_PG21 46
84+
#define R_OR1K_LO13 47
85+
#define R_OR1K_GOT_LO13 48
86+
#define R_OR1K_TLS_GD_LO13 49
87+
#define R_OR1K_TLS_LDM_LO13 50
88+
#define R_OR1K_TLS_IE_LO13 51
89+
#define R_OR1K_SLO13 52
90+
#define R_OR1K_PLTA26 53
91+
#define R_OR1K_GOT_AHI16 54
92+
93+
/* Old relocation names */
94+
#define R_OR32_NONE R_OR1K_NONE
95+
#define R_OR32_32 R_OR1K_32
96+
#define R_OR32_16 R_OR1K_16
97+
#define R_OR32_8 R_OR1K_8
98+
#define R_OR32_CONST R_OR1K_LO_16_IN_INSN
99+
#define R_OR32_CONSTH R_OR1K_HI_16_IN_INSN
100+
#define R_OR32_JUMPTARG R_OR1K_INSN_REL_26
101+
#define R_OR32_VTENTRY R_OR1K_GNU_VTENTRY
102+
#define R_OR32_VTINHERIT R_OR1K_GNU_VTINHERIT
46103

47104
typedef unsigned long elf_greg_t;
48105

arch/openrisc/kernel/entry.S

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@
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 ;\
111109
l.lwz r2,PT_GPR2(r1) ;\
112110
l.lwz r3,PT_GPR3(r1) ;\
113111
l.lwz r4,PT_GPR4(r1) ;\
@@ -177,8 +175,6 @@ handler: ;\
177175
/* r30 already save */ ;\
178176
l.sw PT_GPR31(r1),r31 ;\
179177
TRACE_IRQS_OFF_ENTRY ;\
180-
l.mfspr r30,r0,SPR_FPCSR ;\
181-
l.sw PT_FPCSR(r1),r30 ;\
182178
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
183179
l.addi r30,r0,-1 ;\
184180
l.sw PT_ORIG_GPR11(r1),r30
@@ -219,8 +215,6 @@ handler: ;\
219215
/* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
220216
l.addi r30,r0,-1 ;\
221217
l.sw PT_ORIG_GPR11(r1),r30 ;\
222-
l.mfspr r30,r0,SPR_FPCSR ;\
223-
l.sw PT_FPCSR(r1),r30 ;\
224218
l.addi r3,r1,0 ;\
225219
/* r4 is exception EA */ ;\
226220
l.addi r5,r0,vector ;\
@@ -852,6 +846,7 @@ _syscall_badsys:
852846

853847
EXCEPTION_ENTRY(_fpe_trap_handler)
854848
CLEAR_LWA_FLAG(r3)
849+
855850
/* r4: EA of fault (set by EXCEPTION_HANDLE) */
856851
l.jal do_fpe_trap
857852
l.addi r3,r1,0 /* pt_regs */
@@ -1100,10 +1095,6 @@ ENTRY(_switch)
11001095
l.sw PT_GPR28(r1),r28
11011096
l.sw PT_GPR30(r1),r30
11021097

1103-
/* Store the old FPU state to new pt_regs */
1104-
l.mfspr r29,r0,SPR_FPCSR
1105-
l.sw PT_FPCSR(r1),r29
1106-
11071098
l.addi r11,r10,0 /* Save old 'current' to 'last' return value*/
11081099

11091100
/* We use thread_info->ksp for storing the address of the above
@@ -1126,10 +1117,6 @@ ENTRY(_switch)
11261117
l.lwz r29,PT_SP(r1)
11271118
l.sw TI_KSP(r10),r29
11281119

1129-
/* Restore the old value of FPCSR */
1130-
l.lwz r29,PT_FPCSR(r1)
1131-
l.mtspr r0,r29,SPR_FPCSR
1132-
11331120
/* ...and restore the registers, except r11 because the return value
11341121
* has already been set above.
11351122
*/

arch/openrisc/kernel/module.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,32 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
3939
value = sym->st_value + rel[i].r_addend;
4040

4141
switch (ELF32_R_TYPE(rel[i].r_info)) {
42-
case R_OR32_32:
42+
case R_OR1K_32:
4343
*location = value;
4444
break;
45-
case R_OR32_CONST:
45+
case R_OR1K_LO_16_IN_INSN:
4646
*((uint16_t *)location + 1) = value;
4747
break;
48-
case R_OR32_CONSTH:
48+
case R_OR1K_HI_16_IN_INSN:
4949
*((uint16_t *)location + 1) = value >> 16;
5050
break;
51-
case R_OR32_JUMPTARG:
51+
case R_OR1K_INSN_REL_26:
5252
value -= (uint32_t)location;
5353
value >>= 2;
5454
value &= 0x03ffffff;
5555
value |= *location & 0xfc000000;
5656
*location = value;
5757
break;
58+
case R_OR1K_AHI16:
59+
/* Adjust the operand to match with a signed LO16. */
60+
value += 0x8000;
61+
*((uint16_t *)location + 1) = value >> 16;
62+
break;
63+
case R_OR1K_SLO16:
64+
/* Split value lower 16-bits. */
65+
value = ((value & 0xf800) << 10) | (value & 0x7ff);
66+
*location = (*location & ~0x3e007ff) | value;
67+
break;
5868
default:
5969
pr_err("module %s: Unknown relocation: %u\n",
6070
me->name, ELF32_R_TYPE(rel[i].r_info));

arch/openrisc/kernel/process.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/reboot.h>
3737

3838
#include <linux/uaccess.h>
39+
#include <asm/fpu.h>
3940
#include <asm/io.h>
4041
#include <asm/processor.h>
4142
#include <asm/spr_defs.h>
@@ -65,7 +66,7 @@ void machine_restart(char *cmd)
6566
}
6667

6768
/*
68-
* This is used if pm_power_off has not been set by a power management
69+
* This is used if a sys-off handler was not set by a power management
6970
* driver, in this case we can assume we are on a simulator. On
7071
* OpenRISC simulators l.nop 1 will trigger the simulator exit.
7172
*/
@@ -89,10 +90,8 @@ void machine_halt(void)
8990
void machine_power_off(void)
9091
{
9192
printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
92-
if (pm_power_off != NULL)
93-
pm_power_off();
94-
else
95-
default_power_off();
93+
do_kernel_power_off();
94+
default_power_off();
9695
}
9796

9897
/*
@@ -246,6 +245,8 @@ struct task_struct *__switch_to(struct task_struct *old,
246245

247246
local_irq_save(flags);
248247

248+
save_fpu(current);
249+
249250
/* current_set is an array of saved current pointers
250251
* (one for each cpu). we need them at user->kernel transition,
251252
* while we save them at kernel->user transition
@@ -258,6 +259,8 @@ struct task_struct *__switch_to(struct task_struct *old,
258259
current_thread_info_set[smp_processor_id()] = new_ti;
259260
last = (_switch(old_ti, new_ti))->task;
260261

262+
restore_fpu(current);
263+
261264
local_irq_restore(flags);
262265

263266
return last;

arch/openrisc/kernel/ptrace.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ static int genregs_set(struct task_struct *target,
8888
return ret;
8989
}
9090

91+
#ifdef CONFIG_FPU
9192
/*
9293
* As OpenRISC shares GPRs and floating point registers we don't need to export
9394
* the floating point registers again. So here we only export the fpcsr special
@@ -97,31 +98,28 @@ static int fpregs_get(struct task_struct *target,
9798
const struct user_regset *regset,
9899
struct membuf to)
99100
{
100-
const struct pt_regs *regs = task_pt_regs(target);
101-
102-
return membuf_store(&to, regs->fpcsr);
101+
return membuf_store(&to, target->thread.fpcsr);
103102
}
104103

105104
static int fpregs_set(struct task_struct *target,
106105
const struct user_regset *regset,
107106
unsigned int pos, unsigned int count,
108107
const void *kbuf, const void __user *ubuf)
109108
{
110-
struct pt_regs *regs = task_pt_regs(target);
111-
int ret;
112-
113109
/* FPCSR */
114-
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
115-
&regs->fpcsr, 0, 4);
116-
return ret;
110+
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
111+
&target->thread.fpcsr, 0, 4);
117112
}
113+
#endif
118114

119115
/*
120116
* Define the register sets available on OpenRISC under Linux
121117
*/
122118
enum or1k_regset {
123119
REGSET_GENERAL,
120+
#ifdef CONFIG_FPU
124121
REGSET_FPU,
122+
#endif
125123
};
126124

127125
static const struct user_regset or1k_regsets[] = {
@@ -133,6 +131,7 @@ static const struct user_regset or1k_regsets[] = {
133131
.regset_get = genregs_get,
134132
.set = genregs_set,
135133
},
134+
#ifdef CONFIG_FPU
136135
[REGSET_FPU] = {
137136
.core_note_type = NT_PRFPREG,
138137
.n = sizeof(struct __or1k_fpu_state) / sizeof(long),
@@ -141,6 +140,7 @@ static const struct user_regset or1k_regsets[] = {
141140
.regset_get = fpregs_get,
142141
.set = fpregs_set,
143142
},
143+
#endif
144144
};
145145

146146
static const struct user_regset_view user_or1k_native_view = {

0 commit comments

Comments
 (0)