Move the pmap_setup to the start oea_init (no non-OFW ports can use it).
If PPC_OEA64_BRIDGE is defined, add code so that when OEACPU_64_BRIDGE is not present, it replaces the rfid with rfi and mfmsr/rldicl/mtmsrd sequence with NOPs. This allows plain OEA kernels to work. (tested on PMPPC with PPC_OEA64_BRIDGE option added).
This commit is contained in:
parent
378cec5a74
commit
310fbebba0
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: oea_machdep.c,v 1.65 2013/07/04 22:59:27 joerg Exp $ */
|
||||
/* $NetBSD: oea_machdep.c,v 1.66 2013/08/31 07:33:15 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Matt Thomas
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.65 2013/07/04 22:59:27 joerg Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.66 2013/08/31 07:33:15 matt Exp $");
|
||||
|
||||
#include "opt_ppcarch.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -147,6 +147,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;
|
||||
|
||||
/*
|
||||
@ -298,6 +306,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 +338,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 +359,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 +375,37 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 +426,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 */
|
||||
@ -830,6 +876,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
|
||||
@ -842,13 +893,24 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
__syncicache((void *)exc_exi_base, (int)extsize);
|
||||
|
||||
__asm volatile ("mtmsr %0" :: "r"(omsr));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ofwoea_machdep.c,v 1.33 2013/05/13 00:12:01 macallan Exp $ */
|
||||
/* $NetBSD: ofwoea_machdep.c,v 1.34 2013/08/31 07:33:15 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.33 2013/05/13 00:12:01 macallan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.34 2013/08/31 07:33:15 matt Exp $");
|
||||
|
||||
#include "opt_ppcarch.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -201,13 +201,6 @@ ofwoea_initppc(u_int startkernel, u_int endkernel, char *args)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (PPC_OEA64_BRIDGE) && defined (PPC_OEA)
|
||||
if (oeacpufeat & OEACPU_64_BRIDGE)
|
||||
pmap_setup64bridge();
|
||||
else
|
||||
pmap_setup32();
|
||||
#endif
|
||||
|
||||
oea_init(pic_ext_intr);
|
||||
|
||||
ofmaplen = save_ofmap(NULL, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user