Commit d75439d6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus' of https://github.com/openrisc/linux

Pull OpenRISC updates from Stafford Horne:
 "Two things for OpenRISC this cycle:

   - Small cleanup for device tree cpu iteration from Rob Herring

   - Add support for storing, restoring and accessing user space FPU
     state, to allow for libc to support the FPU on OpenRISC"

* tag 'for-linus' of https://github.com/openrisc/linux:
  openrisc: Add floating point regset
  openrisc: Support floating point user api
  openrisc: Support storing and restoring fpu state
  openrisc: Properly store r31 to pt_regs on unhandled exceptions
  openrisc: Use common of_get_cpu_node() instead of open-coding
parents 3f2a1903 c91b4a07
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct pt_regs {
	 * -1 for all other exceptions.
	 */
	long  orig_gpr11;	/* For restarting system calls */
	long dummy;		/* Cheap alignment fix */
	long fpcsr;		/* Floating point control status register. */
	long dummy2;		/* Cheap alignment fix */
};

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

#endif /* __ASM_OPENRISC_PTRACE_H */
+1 −2
Original line number Diff line number Diff line
@@ -53,8 +53,7 @@ typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];

/* A placeholder; OR32 does not have fp support yes, so no fp regs for now.  */
typedef unsigned long elf_fpregset_t;
typedef struct __or1k_fpu_state elf_fpregset_t;

/* EM_OPENRISC is defined in linux/elf-em.h */
#define EM_OR32         0x8472
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ struct user_regs_struct {
	unsigned long pc;
	unsigned long sr;
};

struct __or1k_fpu_state {
	unsigned long fpcsr;
};
#endif


+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

struct sigcontext {
	struct user_regs_struct regs;  /* needs to be first */
	struct __or1k_fpu_state fpu;
	unsigned long oldmask;
};

+25 −6
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@
	l.mtspr r0,r3,SPR_EPCR_BASE				;\
	l.lwz   r3,PT_SR(r1)					;\
	l.mtspr r0,r3,SPR_ESR_BASE				;\
	l.lwz	r3,PT_FPCSR(r1)					;\
	l.mtspr	r0,r3,SPR_FPCSR					;\
	l.lwz   r2,PT_GPR2(r1)					;\
	l.lwz   r3,PT_GPR3(r1)					;\
	l.lwz   r4,PT_GPR4(r1)					;\
@@ -173,9 +175,10 @@ handler: ;\
	l.sw    PT_GPR28(r1),r28					;\
	l.sw    PT_GPR29(r1),r29					;\
	/* r30 already save */					;\
/*        l.sw    PT_GPR30(r1),r30*/					;\
	l.sw    PT_GPR31(r1),r31					;\
	TRACE_IRQS_OFF_ENTRY						;\
	l.mfspr	r30,r0,SPR_FPCSR				;\
	l.sw	PT_FPCSR(r1),r30				;\
	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\
	l.addi	r30,r0,-1					;\
	l.sw	PT_ORIG_GPR11(r1),r30
@@ -211,12 +214,13 @@ handler: ;\
	l.sw    PT_GPR27(r1),r27					;\
	l.sw    PT_GPR28(r1),r28					;\
	l.sw    PT_GPR29(r1),r29					;\
	/* r31 already saved */					;\
	l.sw    PT_GPR30(r1),r30					;\
/*        l.sw    PT_GPR31(r1),r31	*/				;\
	/* r30 already saved */						;\
	l.sw    PT_GPR31(r1),r31					;\
	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\
	l.addi	r30,r0,-1					;\
	l.sw	PT_ORIG_GPR11(r1),r30				;\
	l.mfspr	r30,r0,SPR_FPCSR				;\
	l.sw	PT_FPCSR(r1),r30				;\
	l.addi	r3,r1,0						;\
	/* r4 is exception EA */				;\
	l.addi	r5,r0,vector					;\
@@ -844,9 +848,16 @@ _syscall_badsys:

/******* END SYSCALL HANDLING *******/

/* ---[ 0xd00: Trap exception ]------------------------------------------ */
/* ---[ 0xd00: Floating Point exception ]-------------------------------- */

UNHANDLED_EXCEPTION(_vector_0xd00,0xd00)
EXCEPTION_ENTRY(_fpe_trap_handler)
	CLEAR_LWA_FLAG(r3)
	/* r4: EA of fault (set by EXCEPTION_HANDLE) */
	l.jal   do_fpe_trap
	 l.addi  r3,r1,0 /* pt_regs */

	l.j     _ret_from_exception
	 l.nop

/* ---[ 0xe00: Trap exception ]------------------------------------------ */

@@ -1089,6 +1100,10 @@ ENTRY(_switch)
	l.sw    PT_GPR28(r1),r28
	l.sw    PT_GPR30(r1),r30

	/* Store the old FPU state to new pt_regs */
	l.mfspr	r29,r0,SPR_FPCSR
	l.sw	PT_FPCSR(r1),r29

	l.addi	r11,r10,0			/* Save old 'current' to 'last' return value*/

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

	/* Restore the old value of FPCSR */
	l.lwz	r29,PT_FPCSR(r1)
	l.mtspr	r0,r29,SPR_FPCSR

	/* ...and restore the registers, except r11 because the return value
	 * has already been set above.
	 */
Loading