From owner-svn-src-head@freebsd.org Fri Apr 20 03:19:46 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1822BF99184; Fri, 20 Apr 2018 03:19:46 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BF9C5685ED; Fri, 20 Apr 2018 03:19:45 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BA86912CF3; Fri, 20 Apr 2018 03:19:45 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3K3JjMl019601; Fri, 20 Apr 2018 03:19:45 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3K3JjQp019596; Fri, 20 Apr 2018 03:19:45 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201804200319.w3K3JjQp019596@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Fri, 20 Apr 2018 03:19:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332807 - in head/sys/powerpc: include powerpc X-SVN-Group: head X-SVN-Commit-Author: jhibbits X-SVN-Commit-Paths: in head/sys/powerpc: include powerpc X-SVN-Commit-Revision: 332807 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Apr 2018 03:19:46 -0000 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 #include +#include #include #include @@ -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: