svn commit: r332807 - in head/sys/powerpc: include powerpc

Justin Hibbits jhibbits at FreeBSD.org
Fri Apr 20 03:19:46 UTC 2018


Author: jhibbits
Date: Fri Apr 20 03:19:44 2018
New Revision: 332807
URL: https://svnweb.freebsd.org/changeset/base/332807

Log:
  powerpc64: Add DSCR support
  
  Summary:
  Powerpc64 has support for a register called Data Stream Control Register
  (DSCR), which basically controls how the hardware controls the caching and
  prefetch for stream operations.
  
  Since mfdscr and mtdscr are privileged instructions, we need to emulate them,
  and
  keep the custom DSCR configuration per thread.
  
  The purpose of this feature is to change DSCR depending on the operation, set
  to DSCR Default Prefetch Depth to deepest on string operations, as memcpy.
  
  Submitted by:	Breno Leitao
  Differential Revision: https://reviews.freebsd.org/D15081

Modified:
  head/sys/powerpc/include/pcb.h
  head/sys/powerpc/include/spr.h
  head/sys/powerpc/powerpc/exec_machdep.c
  head/sys/powerpc/powerpc/genassym.c
  head/sys/powerpc/powerpc/swtch64.S

Modified: head/sys/powerpc/include/pcb.h
==============================================================================
--- head/sys/powerpc/include/pcb.h	Fri Apr 20 03:11:51 2018	(r332806)
+++ head/sys/powerpc/include/pcb.h	Fri Apr 20 03:19:44 2018	(r332807)
@@ -46,14 +46,16 @@ struct pcb {
 	register_t	pcb_sp;			/* stack pointer */
 	register_t	pcb_toc;		/* toc pointer */
 	register_t	pcb_lr;			/* link register */
+	register_t	pcb_dscr;		/* dscr value */
 	struct		pmap *pcb_pm;		/* pmap of our vmspace */
 	jmp_buf		*pcb_onfault;		/* For use during
 						    copyin/copyout */
 	int		pcb_flags;
-#define	PCB_FPU		1	/* Process uses FPU */
-#define	PCB_FPREGS	2	/* Process had FPU registers initialized */
-#define	PCB_VEC		4	/* Process had Altivec initialized */
-#define	PCB_VSX		8	/* Process had VSX initialized */
+#define	PCB_FPU		0x1	/* Process uses FPU */
+#define	PCB_FPREGS	0x2	/* Process had FPU registers initialized */
+#define	PCB_VEC		0x4	/* Process had Altivec initialized */
+#define	PCB_VSX		0x8	/* Process had VSX initialized */
+#define	PCB_CDSCR	0x10	/* Process had Custom DSCR initialized */
 	struct fpu {
 		union {
 			double fpr;

Modified: head/sys/powerpc/include/spr.h
==============================================================================
--- head/sys/powerpc/include/spr.h	Fri Apr 20 03:11:51 2018	(r332806)
+++ head/sys/powerpc/include/spr.h	Fri Apr 20 03:19:44 2018	(r332807)
@@ -97,6 +97,7 @@
 #define	SPR_RTCL_R		0x005	/* .6. 601 RTC Lower - Read */
 #define	SPR_LR			0x008	/* 468 Link Register */
 #define	SPR_CTR			0x009	/* 468 Count Register */
+#define	SPR_DSCR		0x011   /* Data Stream Control Register */
 #define	SPR_DSISR		0x012	/* .68 DSI exception source */
 #define	  DSISR_DIRECT		  0x80000000 /* Direct-store error exception */
 #define	  DSISR_NOTFOUND	  0x40000000 /* Translation not found */

Modified: head/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/exec_machdep.c	Fri Apr 20 03:11:51 2018	(r332806)
+++ head/sys/powerpc/powerpc/exec_machdep.c	Fri Apr 20 03:19:44 2018	(r332807)
@@ -1021,11 +1021,46 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *
 	td->td_retval[1] = 0;
 }
 
+static int
+emulate_mfspr(int spr, int reg, struct trapframe *frame){
+	struct thread *td;
+
+	td = curthread;
+
+	if (spr == SPR_DSCR) {
+		// If DSCR was never set, get the default DSCR
+		if ((td->td_pcb->pcb_flags & PCB_CDSCR) == 0)
+			td->td_pcb->pcb_dscr = mfspr(SPR_DSCR);
+
+		frame->fixreg[reg] = td->td_pcb->pcb_dscr;
+		frame->srr0 += 4;
+		return 0;
+	} else
+		return SIGILL;
+}
+
+static int
+emulate_mtspr(int spr, int reg, struct trapframe *frame){
+	struct thread *td;
+
+	td = curthread;
+
+	if (spr == SPR_DSCR) {
+		td->td_pcb->pcb_flags |= PCB_CDSCR;
+		td->td_pcb->pcb_dscr = frame->fixreg[reg];
+		frame->srr0 += 4;
+		return 0;
+	} else
+		return SIGILL;
+}
+
+#define XFX 0xFC0007FF
 int
 ppc_instr_emulate(struct trapframe *frame, struct pcb *pcb)
 {
 	uint32_t instr;
 	int reg, sig;
+	int rs, spr;
 
 	instr = fuword32((void *)frame->srr0);
 	sig = SIGILL;
@@ -1035,9 +1070,15 @@ ppc_instr_emulate(struct trapframe *frame, struct pcb 
 		frame->fixreg[reg] = mfpvr();
 		frame->srr0 += 4;
 		return (0);
-	}
-
-	if ((instr & 0xfc000ffe) == 0x7c0004ac) {	/* various sync */
+	} else if ((instr & XFX) == 0x7c0002a6) {	/* mfspr */
+		rs = (instr &  0x3e00000) >> 21;
+		spr = (instr & 0x1ff800) >> 16;
+		return emulate_mfspr(spr, rs, frame);
+	} else if ((instr & XFX) == 0x7c0003a6) {	/* mtspr */
+		rs = (instr &  0x3e00000) >> 21;
+		spr = (instr & 0x1ff800) >> 16;
+		return emulate_mtspr(spr, rs, frame);
+	} else if ((instr & 0xfc000ffe) == 0x7c0004ac) {	/* various sync */
 		powerpc_sync(); /* Do a heavy-weight sync */
 		frame->srr0 += 4;
 		return (0);

Modified: head/sys/powerpc/powerpc/genassym.c
==============================================================================
--- head/sys/powerpc/powerpc/genassym.c	Fri Apr 20 03:11:51 2018	(r332806)
+++ head/sys/powerpc/powerpc/genassym.c	Fri Apr 20 03:19:44 2018	(r332807)
@@ -195,6 +195,7 @@ ASSYM(CF_SIZE, sizeof(struct callframe));
 
 ASSYM(PCB_CONTEXT, offsetof(struct pcb, pcb_context));
 ASSYM(PCB_CR, offsetof(struct pcb, pcb_cr));
+ASSYM(PCB_DSCR, offsetof(struct pcb, pcb_dscr));
 ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
 ASSYM(PCB_TOC, offsetof(struct pcb, pcb_toc));
 ASSYM(PCB_LR, offsetof(struct pcb, pcb_lr));
@@ -202,6 +203,7 @@ ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
 ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
 ASSYM(PCB_FPU, PCB_FPU);
 ASSYM(PCB_VEC, PCB_VEC);
+ASSYM(PCB_CDSCR, PCB_CDSCR);
 
 ASSYM(PCB_AIM_USR_VSID, offsetof(struct pcb, pcb_cpu.aim.usr_vsid));
 ASSYM(PCB_BOOKE_DBCR0, offsetof(struct pcb, pcb_cpu.booke.dbcr0));

Modified: head/sys/powerpc/powerpc/swtch64.S
==============================================================================
--- head/sys/powerpc/powerpc/swtch64.S	Fri Apr 20 03:11:51 2018	(r332806)
+++ head/sys/powerpc/powerpc/swtch64.S	Fri Apr 20 03:19:44 2018	(r332807)
@@ -62,6 +62,7 @@
 #include <sys/syscall.h>
 
 #include <machine/trap.h>
+#include <machine/spr.h>
 #include <machine/param.h>
 #include <machine/asm.h>
 
@@ -124,6 +125,14 @@ ENTRY(cpu_switch)
 	
 	stdu	%r1,-48(%r1)
 
+	lwz	%r7, PCB_FLAGS(%r17)
+	andi.	%r7, %r7, PCB_CDSCR
+	beq	.L0
+	/* Custom DSCR was set. Reseting it to enter kernel */
+	li	%r7, 0x0
+	mtspr   SPR_DSCR, %r7
+
+.L0:
 	lwz	%r7,PCB_FLAGS(%r17)
 	/* Save FPU context if needed */
 	andi.	%r7, %r7, PCB_FPU
@@ -188,10 +197,18 @@ blocked_loop:
 	lwz	%r6, PCB_FLAGS(%r17)
 	/* Restore Altivec context if needed */
 	andi.	%r6, %r6, PCB_VEC
-	beq	.L4
+	beq	.L31
 	mr	%r3,%r13		/* Pass curthread to enable_vec */
 	bl	enable_vec
 	nop
+
+.L31:
+	lwz	%r6, PCB_FLAGS(%r17)
+	/* Restore Custom DSCR if needed */
+	andi.	%r6, %r6, PCB_CDSCR
+	beq	.L4
+	ld	%r6, PCB_DSCR(%r17)	/* Load the DSCR register*/
+	mtspr	SPR_DSCR, %r6
 
 	/* thread to restore is in r3 */
 .L4:


More information about the svn-src-all mailing list