Module Name: src
Committed By: bouyer
Date: Mon Nov 16 09:00:01 UTC 2015
Modified Files:
src/sys/arch/powerpc/include [netbsd-6]: psl.h userret.h
src/sys/arch/powerpc/oea [netbsd-6]: altivec.c oea_machdep.c
src/sys/arch/powerpc/powerpc [netbsd-6]: fpu.c
Log Message:
Revert ticket 1310:
> sys/arch/powerpc/include/psl.h 1.20
> sys/arch/powerpc/include/userret.h 1.29, 1.30
> sys/arch/powerpc/oea/altivec.c 1.30
> sys/arch/powerpc/oea/oea_machdep.c 1.72
> sys/arch/powerpc/powerpc/fpu.c 1.36
>
> powerpc PCU fixes
because it breaks the build:
http://releng.netbsd.org/builds/netbsd-6/201511152000Z/
To generate a diff of this commit:
cvs rdiff -u -r1.18.8.1 -r1.18.8.2 src/sys/arch/powerpc/include/psl.h
cvs rdiff -u -r1.22.8.2 -r1.22.8.3 src/sys/arch/powerpc/include/userret.h
cvs rdiff -u -r1.25.8.1 -r1.25.8.2 src/sys/arch/powerpc/oea/altivec.c
cvs rdiff -u -r1.63.2.1 -r1.63.2.2 src/sys/arch/powerpc/oea/oea_machdep.c
cvs rdiff -u -r1.31.8.1 -r1.31.8.2 src/sys/arch/powerpc/powerpc/fpu.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/powerpc/include/psl.h
diff -u src/sys/arch/powerpc/include/psl.h:1.18.8.1 src/sys/arch/powerpc/include/psl.h:1.18.8.2
--- src/sys/arch/powerpc/include/psl.h:1.18.8.1 Sun Nov 15 16:36:57 2015
+++ src/sys/arch/powerpc/include/psl.h Mon Nov 16 09:00:01 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: psl.h,v 1.18.8.1 2015/11/15 16:36:57 bouyer Exp $ */
+/* $NetBSD: psl.h,v 1.18.8.2 2015/11/16 09:00:01 bouyer Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -102,7 +102,8 @@
#include "opt_ppcarch.h"
#endif /* _KERNEL_OPT */
-#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined(_MODULE)
+#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined (PPC_OEA64) \
+ || defined(_MODULE)
extern register_t cpu_psluserset, cpu_pslusermod, cpu_pslusermask;
#define PSL_USERSET cpu_psluserset
Index: src/sys/arch/powerpc/include/userret.h
diff -u src/sys/arch/powerpc/include/userret.h:1.22.8.2 src/sys/arch/powerpc/include/userret.h:1.22.8.3
--- src/sys/arch/powerpc/include/userret.h:1.22.8.2 Sun Nov 15 16:36:57 2015
+++ src/sys/arch/powerpc/include/userret.h Mon Nov 16 09:00:01 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: userret.h,v 1.22.8.2 2015/11/15 16:36:57 bouyer Exp $ */
+/* $NetBSD: userret.h,v 1.22.8.3 2015/11/16 09:00:01 bouyer Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -58,6 +58,14 @@ userret(struct lwp *l, struct trapframe
/* Invoke MI userret code */
mi_userret(l);
+ KASSERTMSG((tf->tf_srr1 & PSL_PR) != 0,
+ "tf=%p: srr1 (%#lx): PSL_PR isn't set!",
+ tf, tf->tf_srr1);
+ KASSERTMSG((tf->tf_srr1 & PSL_FP) == 0
+ || l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU] == l,
+ "tf=%p: srr1 (%#lx): PSL_FP set but FPU curlwp %p is not curlwp %p!",
+ tf, tf->tf_srr1, l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU], l);
+
/* clear SRR1 status bits */
tf->tf_srr1 &= (PSL_USERSRR1|PSL_FP|PSL_VEC);
@@ -71,12 +79,12 @@ userret(struct lwp *l, struct trapframe
#endif
#ifdef PPC_BOOKE
/*
- * BookE doesn't PSL_SE but it does have a debug instruction completion
- * exception but it needs PSL_DE to fire. Since we don't want it to
- * happen in the kernel, we must disable PSL_DE and let it get
- * restored by rfi/rfci.
+ * BookE doesn't have PSL_SE but it does have a debug instruction
+ * completion exception but it needs PSL_DE to fire. Instead we
+ * use IAC1/IAC2 to match the next PC.
*/
if (__predict_false(tf->tf_srr1 & PSL_SE)) {
+ tf->tf_srr1 &= ~PSL_SE;
extern void booke_sstep(struct trapframe *); /* ugly */
booke_sstep(tf);
}
Index: src/sys/arch/powerpc/oea/altivec.c
diff -u src/sys/arch/powerpc/oea/altivec.c:1.25.8.1 src/sys/arch/powerpc/oea/altivec.c:1.25.8.2
--- src/sys/arch/powerpc/oea/altivec.c:1.25.8.1 Sun Nov 15 16:36:57 2015
+++ src/sys/arch/powerpc/oea/altivec.c Mon Nov 16 09:00:01 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: altivec.c,v 1.25.8.1 2015/11/15 16:36:57 bouyer Exp $ */
+/* $NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.1 2015/11/15 16:36:57 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $");
#include "opt_multiprocessor.h"
@@ -49,7 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: altivec.c,v
#include <powerpc/oea/spr.h>
#include <powerpc/psl.h>
-static void vec_state_load(lwp_t *, bool);
+static void vec_state_load(lwp_t *, u_int);
static void vec_state_save(lwp_t *);
static void vec_state_release(lwp_t *);
@@ -63,21 +63,21 @@ const pcu_ops_t vec_ops = {
bool
vec_used_p(lwp_t *l)
{
- return (l->l_md.md_flags & MDLWP_USEDVEC) != 0;
+ return pcu_valid_p(&vec_ops);
}
void
vec_mark_used(lwp_t *l)
{
- l->l_md.md_flags |= MDLWP_USEDVEC;
+ return pcu_discard(&vec_ops, true);
}
void
-vec_state_load(lwp_t *l, bool used)
+vec_state_load(lwp_t *l, u_int flags)
{
struct pcb * const pcb = lwp_getpcb(l);
- if (__predict_false(!vec_used_p(l))) {
+ if ((flags & PCU_VALID) == 0) {
memset(&pcb->pcb_vr, 0, sizeof(pcb->pcb_vr));
vec_mark_used(l);
}
@@ -111,7 +111,7 @@ vec_state_load(lwp_t *l, bool used)
/*
* Mark vector registers as modified.
*/
- l->l_md.md_flags |= MDLWP_USEDVEC|PSL_VEC;
+ l->l_md.md_flags |= PSL_VEC;
l->l_md.md_utf->tf_srr1 |= PSL_VEC;
}
@@ -166,7 +166,7 @@ vec_restore_from_mcontext(struct lwp *l,
KASSERT(l == curlwp);
/* we don't need to save the state, just drop it */
- pcu_discard(&vec_ops);
+ pcu_discard(&vec_ops, true);
memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg));
pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;
Index: src/sys/arch/powerpc/oea/oea_machdep.c
diff -u src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.1 src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.2
--- src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.1 Sun Nov 15 16:36:57 2015
+++ src/sys/arch/powerpc/oea/oea_machdep.c Mon Nov 16 09:00:01 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: oea_machdep.c,v 1.63.2.1 2015/11/15 16:36:57 bouyer Exp $ */
+/* $NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.1 2015/11/15 16:36:57 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $");
#include "opt_ppcarch.h"
#include "opt_compat_netbsd.h"
@@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: oea_machdep.
#include <sys/syscallargs.h>
#include <sys/syslog.h>
#include <sys/systm.h>
+#include <sys/cpu.h>
#include <uvm/uvm_extern.h>
@@ -147,6 +148,14 @@ oea_init(void (*handler)(void))
#endif
KASSERT(mfspr(SPR_SPRG0) == (uintptr_t)ci);
+#if defined (PPC_OEA64_BRIDGE) && defined (PPC_OEA)
+ if (oeacpufeat & OEACPU_64_BRIDGE)
+ pmap_setup64bridge();
+ else
+ pmap_setup32();
+#endif
+
+
cpuvers = mfpvr() >> 16;
/*
@@ -280,8 +289,8 @@ oea_init(void (*handler)(void))
* Install a branch absolute to trap0 to force a panic.
*/
if ((uintptr_t)trap0 < 0x2000000) {
- *(uint32_t *) 0 = 0x7c6802a6;
- *(uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
+ *(volatile uint32_t *) 0 = 0x7c6802a6;
+ *(volatile uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
}
/*
@@ -298,6 +307,16 @@ oea_init(void (*handler)(void))
#define B 0x48000000
#define TLBSYNC 0x7c00046c
#define SYNC 0x7c0004ac
+#ifdef PPC_OEA64_BRIDGE
+#define MFMSR_MASK 0xfc1fffff
+#define MFMSR 0x7c0000a6
+#define MTMSRD_MASK 0xfc1effff
+#define MTMSRD 0x7c000164
+#define RLDICL_MASK 0xfc00001c
+#define RLDICL 0x78000000
+#define RFID 0x4c000024
+#define RFI 0x4c000064
+#endif
#ifdef ALTIVEC
#define MFSPR_VRSAVE 0x7c0042a6
@@ -320,9 +339,7 @@ oea_init(void (*handler)(void))
if (scratch & PSL_VEC) {
cpu_altivec = 1;
} else {
- int *ip = trapstart;
-
- for (; ip < trapend; ip++) {
+ for (int *ip = trapstart; ip < trapend; ip++) {
if ((ip[0] & MxSPR_MASK) == MFSPR_VRSAVE) {
ip[0] = NOP; /* mfspr */
ip[1] = NOP; /* stw */
@@ -343,9 +360,7 @@ oea_init(void (*handler)(void))
* sequences where we zap/restore BAT registers on kernel exit/entry.
*/
if (cpuvers != MPC601) {
- int *ip = trapstart;
-
- for (; ip < trapend; ip++) {
+ for (int *ip = trapstart; ip < trapend; ip++) {
if ((ip[0] & MxSPR_MASK) == MFSPR_MQ) {
ip[0] = NOP; /* mfspr */
ip[1] = NOP; /* stw */
@@ -361,6 +376,39 @@ oea_init(void (*handler)(void))
}
}
+#ifdef PPC_OEA64_BRIDGE
+ if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) {
+ for (int *ip = (int *)exc_base;
+ (uintptr_t)ip <= exc_base + EXC_LAST;
+ ip++) {
+ if ((ip[0] & MFMSR_MASK) == MFMSR
+ && (ip[1] & RLDICL_MASK) == RLDICL
+ && (ip[2] & MTMSRD_MASK) == MTMSRD) {
+ *ip++ = NOP;
+ *ip++ = NOP;
+ ip[0] = NOP;
+ } else if (*ip == RFID) {
+ *ip = RFI;
+ }
+ }
+
+ /*
+ * Now replace each rfid instruction with a rfi instruction.
+ */
+ for (int *ip = trapstart; ip < trapend; ip++) {
+ if ((ip[0] & MFMSR_MASK) == MFMSR
+ && (ip[1] & RLDICL_MASK) == RLDICL
+ && (ip[2] & MTMSRD_MASK) == MTMSRD) {
+ *ip++ = NOP;
+ *ip++ = NOP;
+ ip[0] = NOP;
+ } else if (*ip == RFID) {
+ *ip = RFI;
+ }
+ }
+ }
+#endif /* PPC_OEA64_BRIDGE */
+
/*
* Sync the changed instructions.
*/
@@ -381,10 +429,11 @@ oea_init(void (*handler)(void))
extern int kernel_text[], etext[];
int *ip;
- for (ip = kernel_text; ip < etext; ip++)
+ for (ip = kernel_text; ip < etext; ip++) {
if (*ip == TLBSYNC) {
*ip = SYNC;
__syncicache(ip, sizeof(*ip));
+ }
}
}
#endif /* PPC_OEA601 */
@@ -445,9 +494,16 @@ mpc601_ioseg_add(paddr_t pa, register_t
* in pmap_bootstrap().
*/
iosrtable[i] = SR601(SR601_Ks, SR601_BUID_MEMFORCED, 0, i);
+
+ /*
+ * XXX Setting segment register 0xf on my powermac 7200
+ * wedges machine so set later in pmap.c
+ */
+ /*
__asm volatile ("mtsrin %0,%1"
:: "r"(iosrtable[i]),
"r"(pa));
+ */
}
#endif /* PPC_OEA601 */
@@ -470,12 +526,25 @@ void
oea_iobat_add(paddr_t pa, register_t len)
{
static int z = 1;
- const u_int n = __SHIFTOUT(len, (BAT_XBL|BAT_BL) & ~BAT_BL_8M);
+ const u_int n = BAT_BL_TO_SIZE(len) / BAT_BL_TO_SIZE(BAT_BL_8M);
const u_int i = BAT_VA2IDX(pa) & -n; /* in case pa was in the middle */
const int after_bat3 = (oeacpufeat & OEACPU_HIGHBAT) ? 4 : 8;
KASSERT(len >= BAT_BL_8M);
+ /*
+ * If the caller wanted a bigger BAT than the hardware supports,
+ * split it into smaller BATs.
+ */
+ if (len > BAT_BL_256M && (oeacpufeat & OEACPU_XBSEN) == 0) {
+ u_int xn = BAT_BL_TO_SIZE(len) >> 28;
+ while (xn-- > 0) {
+ oea_iobat_add(pa, BAT_BL_256M);
+ pa += 0x10000000;
+ }
+ return;
+ }
+
const register_t batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW);
const register_t batu = BATU(pa, len, BAT_Vs);
@@ -592,11 +661,14 @@ void
oea_batinit(paddr_t pa, ...)
{
struct mem_region *allmem, *availmem, *mp;
- unsigned int cpuvers;
register_t msr = mfmsr();
va_list ap;
+#ifdef PPC_OEA601
+ unsigned int cpuvers;
cpuvers = mfpvr() >> 16;
+#endif /* PPC_OEA601 */
+
/*
* we need to call this before zapping BATs so OF calls work
*/
@@ -813,6 +885,11 @@ oea_install_extint(void (*handler)(void)
extern int extint[], extsize[];
extern int extint_call[];
uintptr_t offset = (uintptr_t)handler - (uintptr_t)extint_call;
+#ifdef PPC_HIGH_VEC
+ const uintptr_t exc_exi_base = EXC_HIGHVEC + EXC_EXI;
+#else
+ const uintptr_t exc_exi_base = EXC_EXI;
+#endif
int omsr, msr;
#ifdef DIAGNOSTIC
@@ -825,13 +902,26 @@ oea_install_extint(void (*handler)(void)
: "K" ((u_short)~PSL_EE));
extint_call[0] = (extint_call[0] & 0xfc000003) | offset;
__syncicache((void *)extint_call, sizeof extint_call[0]);
-#ifdef PPC_HIGH_VEC
- memcpy((void *)(EXC_HIGHVEC + EXC_EXI), extint, (size_t)extsize);
- __syncicache((void *)(EXC_HIGHVEC + EXC_EXI), (int)extsize);
-#else
- memcpy((void *)EXC_EXI, extint, (size_t)extsize);
- __syncicache((void *)EXC_EXI, (int)extsize);
+ memcpy((void *)exc_exi_base, extint, (size_t)extsize);
+#ifdef PPC_OEA64_BRIDGE
+ if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) {
+ for (int *ip = (int *)exc_exi_base;
+ (uintptr_t)ip <= exc_exi_base + (size_t)extsize;
+ ip++) {
+ if ((ip[0] & MFMSR_MASK) == MFMSR
+ && (ip[1] & RLDICL_MASK) == RLDICL
+ && (ip[2] & MTMSRD_MASK) == MTMSRD) {
+ *ip++ = NOP;
+ *ip++ = NOP;
+ ip[0] = NOP;
+ } else if (*ip == RFID) {
+ *ip = RFI;
+ }
+ }
+ }
#endif
+ __syncicache((void *)exc_exi_base, (size_t)extsize);
+
__asm volatile ("mtmsr %0" :: "r"(omsr));
}
@@ -844,7 +934,7 @@ oea_startup(const char *model)
uintptr_t sz;
void *v;
vaddr_t minaddr, maxaddr;
- char pbuf[9];
+ char pbuf[9], mstr[128];
KASSERT(curcpu() != NULL);
KASSERT(lwp0.l_cpu != NULL);
@@ -881,7 +971,8 @@ oea_startup(const char *model)
printf("%s%s", copyright, version);
if (model != NULL)
printf("Model: %s\n", model);
- cpu_identify(NULL, 0);
+ cpu_identify(mstr, sizeof(mstr));
+ cpu_setmodel("%s", mstr);
format_bytes(pbuf, sizeof(pbuf), ctob((u_int)physmem));
printf("total memory = %s\n", pbuf);
Index: src/sys/arch/powerpc/powerpc/fpu.c
diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.1 src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.2
--- src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.1 Sun Nov 15 16:36:57 2015
+++ src/sys/arch/powerpc/powerpc/fpu.c Mon Nov 16 09:00:01 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.31.8.1 2015/11/15 16:36:57 bouyer Exp $ */
+/* $NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.1 2015/11/15 16:36:57 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $");
#include "opt_multiprocessor.h"
@@ -48,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31
#include <machine/psl.h>
#ifdef PPC_HAVE_FPU
-static void fpu_state_load(lwp_t *, bool);
+static void fpu_state_load(lwp_t *, u_int);
static void fpu_state_save(lwp_t *);
static void fpu_state_release(lwp_t *);
#endif
@@ -65,24 +65,23 @@ const pcu_ops_t fpu_ops = {
bool
fpu_used_p(lwp_t *l)
{
- return (l->l_md.md_flags & MDLWP_USEDFPU) != 0;
+ return pcu_valid_p(&fpu_ops);
}
void
fpu_mark_used(lwp_t *l)
{
- l->l_md.md_flags |= MDLWP_USEDFPU;
+ pcu_discard(&fpu_ops, true);
}
#ifdef PPC_HAVE_FPU
void
-fpu_state_load(lwp_t *l, bool used)
+fpu_state_load(lwp_t *l, u_int flags)
{
struct pcb * const pcb = lwp_getpcb(l);
- if (__predict_false(!fpu_used_p(l))) {
+ if ((flags & PCU_VALID) == 0) {
memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
- fpu_mark_used(l);
}
if ((flags & PCU_REENABLE) == 0) {
@@ -99,7 +98,6 @@ fpu_state_load(lwp_t *l, bool used)
curcpu()->ci_ev_fpusw.ev_count++;
l->l_md.md_utf->tf_srr1 |= PSL_FP|(pcb->pcb_flags & (PCB_FE0|PCB_FE1));
- l->l_md.md_flags |= MDLWP_USEDFPU;
}
/*
@@ -215,7 +213,7 @@ fpu_save_to_mcontext(lwp_t *l, mcontext_
{
KASSERT(l == curlwp);
- if (!pcu_used_p(&fpu_ops))
+ if (!pcu_valid_p(&fpu_ops))
return false;
struct pcb * const pcb = lwp_getpcb(l);
@@ -244,7 +242,7 @@ fpu_restore_from_mcontext(lwp_t *l, cons
#ifdef PPC_HAVE_FPU
/* we don't need to save the state, just drop it */
if (l == curlwp)
- pcu_discard(&fpu_ops);
+ pcu_discard(&fpu_ops, true);
#endif
(void)memcpy(&pcb->pcb_fpu.fpreg, &mcp->__fpregs.__fpu_regs,
sizeof (pcb->pcb_fpu.fpreg));