summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>1999-07-05 20:56:27 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>1999-07-05 20:56:27 +0000
commit686744de75a0fa112f4153eaa2516caf2b1c30f9 (patch)
treec615f969109e599806ab8783e8e8323d98161334 /sys
parent00f565c342c7e2b66b9aa63c07e8d9777d3d255d (diff)
Several changes here:
(Some of these changes are work in progress and may change more later) locore.S: rearranged to remove most of the direct openfirmware references in the attempt to move all of the openfirmware pieces into ofw_ files. This could allow other firmware type to be supported easier. Also this keeps the openfirmware code grouped in the same files. OF_buf is now statically allocated in the data/bss section instead of allocated during initialization. machdep.c: change the order of vm initialization, Still considering removing the BATs from use. instead of calls directly to ppc_exit and ppc_boot these are now called via a firmware function pointer structure. Add iMac recognition to systems ofw_machdep.c: function pointer structure to allow different firmware to supply specific system functionality, normally startup and reset, including a hook to notify when bsd is about to go virtual, in case firmware calls need to act different after that time. Allow BSD to handle the virtual memory operations for openfirmware. this idea was copied from NetBSD macppc, It is not fully implemented, among other problems, openfirmware does not have a mechanism to add new mappings. ofwreal.S: Major rewrite of the firmware call code, It still copies a portion of the stack, but now does not restore exeception vectors. Modified to be similar in idea to NetBSD macppc with BSD handling the openfirmware VM faults/TLB misses. This still needs to be reviewed, Should be possible to not require any stack copy. opendev.c: OF_bus is not a pointer to the buffer, but is the buffer itself now. openfirm.c: OF_bus is not a pointer to the buffer, but is the buffer itself now. Dont panic if OF_boot fails, OF_boot can be called by panic. instead print and the hang in a spin loop. pmap.c: call the firmware function to get memory regions. Scale the PowerPC hash table size by size of real memory. Properly align the hash table based on the start, not just the size.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/powerpc/powerpc/locore.S174
-rw-r--r--sys/arch/powerpc/powerpc/machdep.c53
-rw-r--r--sys/arch/powerpc/powerpc/ofw_machdep.c102
-rw-r--r--sys/arch/powerpc/powerpc/ofwreal.S428
-rw-r--r--sys/arch/powerpc/powerpc/opendev.c4
-rw-r--r--sys/arch/powerpc/powerpc/openfirm.c7
-rw-r--r--sys/arch/powerpc/powerpc/pmap.c22
7 files changed, 483 insertions, 307 deletions
diff --git a/sys/arch/powerpc/powerpc/locore.S b/sys/arch/powerpc/powerpc/locore.S
index 29e41708879..ff37cc5b498 100644
--- a/sys/arch/powerpc/powerpc/locore.S
+++ b/sys/arch/powerpc/powerpc/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.7 1998/08/25 07:55:19 pefo Exp $ */
+/* $OpenBSD: locore.S,v 1.8 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */
/*
@@ -49,26 +49,39 @@
*/
.globl _C_LABEL(esym),_C_LABEL(proc0paddr)
.data
-_C_LABEL(esym): .long 0 /* end of symbol table */
-_C_LABEL(proc0paddr): .long 0 /* proc0 p_addr */
-idle_u: .long 0 /* fake uarea during idle after exit */
-openfirmware_entry: .long 0 /* openfirmware entry point */
+_C_LABEL(esym): .long 0 /* end of symbol table */
+_C_LABEL(proc0paddr): .long 0 /* proc0 p_addr */
+idle_u: .long 0 /* fake uarea during idle after exit */
+
+ .globl _C_LABEL(where)
+_C_LABEL(where): .long 0
/*
* Startup entry
*/
_ENTRY(_C_LABEL(kernel_text))
_ENTRY(_ASM_LABEL(start))
+/* arguments to start
+ * r1 - stack provided by firmware/bootloader
+ * r3 - unused
+ * r4 - unused
+ * r5 - firmware pointer (NULL for PPC1bug)
+ * r6 - arg list
+ * r7 - length
+ */
.globl start
start:
-#ifdef FIREPOWERBUGS
- mfmsr 0
- andi. 0,0,PSL_IR|PSL_DR
- beq 1f
-
- bl _C_LABEL(ofwr_init)
-1:
-#endif
+#ifdef SUPPORT_PPC1BUG
+ mr 0,5
+ cmpwi 0,0,0
+ bne 1f
+ /* need additional tests for other systems??? */
+ bl ppc1bug_init
+ b 2f
+#endif /* SUPPORT_PPC1BUG
+1: /* support openfirmware for Apple and PowerStack w/OFW, ... */
+ bl ofw_init
+2:
li 0,0
mtmsr 0 /* Disable FPU/MMU/exceptions */
isync
@@ -76,6 +89,7 @@ start:
/* compute end of kernel memory */
lis 8,_end@ha
addi 8,8,_end@l
+#if 0
#if defined(DDB) || defined(KERNFS)
lwz 9,0(8) /* number of symbols */
add 8,8,9
@@ -84,12 +98,10 @@ start:
lis 9,_C_LABEL(esym)@ha
stw 8,_C_LABEL(esym)@l(9) /* save for symbol handling */
#endif
+#endif
li 9,PGOFSET
add 8,8,9
andc 8,8,9
- lis 9,_C_LABEL(OF_buf)@ha
- stw 8,_C_LABEL(OF_buf)@l(9)
- addi 8,8,NBPG
lis 9,idle_u@ha
stw 8,idle_u@l(9)
addi 8,8,USPACE /* space for idle_u */
@@ -100,114 +112,53 @@ start:
xor 0,0,0
stwu 0,-16(1) /* end of stack chain */
- lis 8,openfirmware_entry@ha
- stw 5,openfirmware_entry@l(8) /* save client interface handler */
+ li 0, 2
+ lis 9,_C_LABEL(where)@ha
+ stw 0,_C_LABEL(where)@l(9)
+
lis 3,start@ha
addi 3,3,start@l
mr 5,6 /* args string */
bl _C_LABEL(initppc)
bl _C_LABEL(main)
b _C_LABEL(OF_exit)
+
+#define LED_ADDR 0x800008c0
+_ENTRY(_C_LABEL(led_dbg))
+ stwu 1,-32(1)
+ mflr 0
+ stw 0,36(1)
-/*
- * OpenFirmware entry point
- */
-_ENTRY(_C_LABEL(openfirmware))
- mflr 0 /* save return address */
- stw 0,4(1)
- stwu 1,-16(1) /* setup stack frame */
-
- mfmsr 4 /* save msr */
stw 4,8(1)
-
- lis 4,openfirmware_entry@ha /* get firmware entry point */
- lwz 4,openfirmware_entry@l(4)
- mtlr 4
-
- li 0,0 /* turn off any ints/mmu/etc. */
- mtmsr 0
+ stw 5,12(1)
+ stw 6,16(1)
+ stw 7,20(1)
+ mfmsr 5
+
+ mr 6,5
+ ori 6,6,(PSL_IR|PSL_DR)@l /* turn on MMU */
+ mtmsr 6
+ sync
isync
- blrl /* call OpenFirmware */
+ lis 4,LED_ADDR@ha
+ addi 4,4,LED_ADDR@l
+ li 7,0
+ ori 3,3,0x2000
+ sthbrx 3,7,4
- lwz 4,8(1) /* restore msr */
- mtmsr 4
+ sync
+ mtmsr 5
isync
+ lwz 4,8(1)
+ lwz 5,12(1)
+ lwz 6,16(1)
+ lwz 7,20(1)
- lwz 1,0(1) /* and return */
- lwz 0,4(1)
- mtlr 0
- blr
-
-/*
- * Switch to/from OpenFirmware real mode stack
- *
- * Note: has to be called as the very first thing in OpenFirmware interface routines.
- * E.g.:
- * int
- * OF_xxx(arg1, arg2)
- * type arg1, arg2;
- * {
- * static struct {
- * char *name;
- * int nargs;
- * int nreturns;
- * char *method;
- * int arg1;
- * int arg2;
- * int ret;
- * } args = {
- * "xxx",
- * 2,
- * 1,
- * };
- *
- * ofw_stack();
- * args.arg1 = arg1;
- * args.arg2 = arg2;
- * if (openfirmware(&args) < 0)
- * return -1;
- * return args.ret;
- * }
- */
-.lcomm firmstk,NBPG,8
-
-_ENTRY(_C_LABEL(ofw_stack))
- mfmsr 8 /* turn off interrupts */
- andi. 0,8,~(PSL_EE|PSL_RI)@l
- mtmsr 0
- stw 8,4(1) /* abuse return address slot */
-
- lwz 5,0(1) /* get length of stack frame */
- subf 5,1,5
-
- lis 7,firmstk+NBPG-8@ha
- addi 7,7,firmstk+NBPG-8@l
- lis 6,ofw_back@ha
- addi 6,6,ofw_back@l
- subf 4,5,7 /* make room for stack frame on new stack */
- stw 6,-4(7) /* setup return pointer */
- stwu 1,-8(7)
-
- stw 7,-8(4)
-
- addi 3,1,8
- addi 1,4,-8
- subi 5,5,8
-
- b _C_LABEL(ofbcopy) /* and copy it */
-
-ofw_back:
- lwz 1,0(1) /* get callers original stack pointer */
-
- lwz 0,4(1) /* get saved msr from abused slot */
- mtmsr 0
-
- lwz 1,0(1) /* return */
- lwz 0,4(1)
+ lwz 0,36(1)
mtlr 0
+ addi 1,1,32
blr
-
/*
* No processes are runnable, so loop waiting for one.
@@ -261,7 +212,7 @@ _ENTRY(_C_LABEL(cpu_switch))
mr 30,3
lis 3,_C_LABEL(curproc)@ha
xor 31,31,31
- stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */
+ stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */
lis 3,_C_LABEL(curpcb)@ha
lwz 31,_C_LABEL(curpcb)@l(3)
@@ -271,7 +222,8 @@ _ENTRY(_C_LABEL(cpu_switch))
/* Find a new process */
mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while manipulating runque */
+ andi. 3,3,~PSL_EE@l /* disable interrupts while
+ manipulating runque */
mtmsr 3
isync
diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c
index a7b9d6c6772..0dd8c717c33 100644
--- a/sys/arch/powerpc/powerpc/machdep.c
+++ b/sys/arch/powerpc/powerpc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.24 1999/05/24 23:09:07 jason Exp $ */
+/* $OpenBSD: machdep.c,v 1.25 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -96,6 +96,7 @@ char ofw_eth_addr[6]; /* Save address of first network ifc found */
char *bootpath;
char bootpathbuf[512];
+struct firmware *fw = NULL;
/*
* We use the page just above the interrupt vector as message buffer
@@ -107,6 +108,8 @@ caddr_t allocsys __P((caddr_t));
int power4e_get_eth_addr __P((void));
+extern int OF_stdout;
+extern int where;
void
initppc(startkernel, endkernel, args)
u_int startkernel, endkernel;
@@ -133,11 +136,11 @@ initppc(startkernel, endkernel, args)
proc0.p_addr = proc0paddr;
bzero(proc0.p_addr, sizeof *proc0.p_addr);
+where = 3;
curpcb = &proc0paddr->u_pcb;
curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();
-
/*
* Initialize BAT registers to unmapped to not generate
* overlapping mappings below.
@@ -157,12 +160,16 @@ initppc(startkernel, endkernel, args)
battable[0].batl = BATL(0x00000000, BAT_M);
battable[0].batu = BATU(0x00000000);
+ battable[1].batl = BATL(MPC106_V_ISA_IO_SPACE, BAT_I);
+ battable[1].batu = BATU(MPC106_P_ISA_IO_SPACE);
+#if 0
if(system_type == POWER4e) {
/* Map ISA I/O */
addbatmap(MPC106_V_ISA_IO_SPACE, MPC106_P_ISA_IO_SPACE, BAT_I);
battable[1].batl = BATL(0xbfffe000, BAT_I);
battable[1].batu = BATU(0xbfffe000);
}
+#endif
/*
* Now setup fixed bat registers
@@ -177,10 +184,9 @@ initppc(startkernel, endkernel, args)
__asm__ volatile ("mtdbatl 0,%0; mtdbatu 0,%1"
:: "r"(battable[0].batl), "r"(battable[0].batu));
-#if 1
__asm__ volatile ("mtdbatl 1,%0; mtdbatu 1,%1"
:: "r"(battable[1].batl), "r"(battable[1].batu));
-#endif
+ __asm__ volatile ("sync;isync");
/*
* Set up trap vectors
@@ -195,12 +201,14 @@ initppc(startkernel, endkernel, args)
* This one is (potentially) installed during autoconf
*/
break;
+#if 1
case EXC_DSI:
bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
break;
case EXC_ISI:
bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
break;
+#endif
case EXC_DECR:
bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize);
break;
@@ -227,15 +235,20 @@ initppc(startkernel, endkernel, args)
/*
* Now enable translation (and machine checks/recoverable interrupts).
*/
- __asm__ volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0; isync"
- : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
+ (fw->vmon)();
+ #if 0
+ #endif
- ofwconprobe();
+ vm_set_page_size();
/*
- * Now we can set up the console as mapping is enabled.
- */
- consinit();
+ * Initialize pmap module.
+ */
+ pmap_bootstrap(startkernel, endkernel);
+
+ __asm__ volatile ("eieio; mfmsr %0; ori %0,%0,%1; mtmsr %0; sync;isync"
+ : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
+
/*
* Look at arguments passed to us and compute boothowto.
@@ -288,11 +301,14 @@ initppc(startkernel, endkernel, args)
#endif
#endif
+ ofwconprobe();
+
/*
- * Initialize pmap module.
- */
- pmap_bootstrap(startkernel, endkernel);
+ * Now we can set up the console as mapping is enabled.
+ */
+ consinit();
+ printf("hello\n");
/*
* Figure out ethernet address.
*/
@@ -767,7 +783,7 @@ boot(howto)
if (howto & RB_HALT) {
doshutdownhooks();
printf("halted\n\n");
- ppc_exit();
+ (fw->exit)();
}
if (!cold && (howto & RB_DUMP))
dumpsys();
@@ -792,7 +808,8 @@ boot(howto)
if (ap[-2] == '-')
*ap1 = 0;
#endif
- ppc_boot(str);
+ OF_exit();
+ (fw->boot)(str);
}
/*
@@ -852,8 +869,9 @@ systype(char *name)
char *systypename;
int type;
} systypes[] = {
- { "MOT,", "(PWRSTK) MCG powerstack family", PWRSTK },
+ { "MOT", "(PWRSTK) MCG powerstack family", PWRSTK },
{ "V-I Power", "(POWER4e) V-I ppc vme boards ", POWER4e},
+ { "iMac", "(APPL) Apple iMac ", APPL},
{ NULL,"",0}
};
for (i = 0; systypes[i].name != NULL; i++) {
@@ -867,7 +885,8 @@ systype(char *name)
}
}
if (system_type == OFWMACH) {
- printf("System type not recognized, good luck\n");
+ printf("System type %snot recognized, good luck\n",
+ name);
}
}
/*
diff --git a/sys/arch/powerpc/powerpc/ofw_machdep.c b/sys/arch/powerpc/powerpc/ofw_machdep.c
index 6aa925c6cfb..f80ae668e6b 100644
--- a/sys/arch/powerpc/powerpc/ofw_machdep.c
+++ b/sys/arch/powerpc/powerpc/ofw_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_machdep.c,v 1.9 1998/09/27 03:56:00 rahnds Exp $ */
+/* $OpenBSD: ofw_machdep.c,v 1.10 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */
/*
@@ -43,11 +43,26 @@
#include <sys/stat.h>
#include <sys/systm.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
#include <machine/powerpc.h>
#include <machine/autoconf.h>
void OF_exit __P((void)) __attribute__((__noreturn__));
void OF_boot __P((char *bootspec)) __attribute__((__noreturn__));
+void ofw_mem_regions __P((struct mem_region **memp, struct mem_region **availp));
+void ofw_vmon __P((void));
+
+struct firmware ofw_firmware = {
+ ofw_mem_regions,
+ OF_exit,
+ OF_boot,
+ ofw_vmon
+#ifdef FW_HAS_PUTC
+ ofwcnputc;
+#endif
+};
#define OFMEM_REGIONS 32
static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
@@ -60,7 +75,7 @@ static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
* to provide space for two additional entry beyond the terminating one.
*/
void
-mem_regions(memp, availp)
+ofw_mem_regions(memp, availp)
struct mem_region **memp, **availp;
{
int phandle, i, j, cnt;
@@ -80,17 +95,85 @@ mem_regions(memp, availp)
*availp = OFavail;
}
+typedef void (fwcall_f) __P((int, int));
+extern fwcall_f *fwcall;
+fwcall_f fwentry;
+extern u_int32_t ofmsr;
+
void
-ppc_exit()
+ofw_vmon()
{
- OF_exit();
+ fwcall = &fwentry;
}
-void
-ppc_boot(str)
- char *str;
+/* code to save and create the necessary mappings for BSD to handle
+ * the vm-setup for OpenFirmware
+ */
+static int N_mapping;
+static struct {
+ vm_offset_t va;
+ int len;
+ vm_offset_t pa;
+ int mode;
+} ofw_mapping[256];
+
+int OF_stdout;
+int
+save_ofw_mapping()
{
- OF_boot(str);
+ int mmui, mmu;
+ int chosen;
+ int stdout;
+ if ((chosen = OF_finddevice("/chosen")) == -1) {
+ return 0;
+ }
+ if (OF_getprop(chosen, "stdout", &stdout, sizeof stdout) != sizeof stdout)
+ {
+ return 0;
+ }
+ OF_stdout = stdout;
+
+ chosen = OF_finddevice("/chosen");
+
+ OF_getprop(chosen, "mmu", &mmui, 4);
+ mmu = OF_instance_to_package(mmui);
+ bzero(ofw_mapping, sizeof(ofw_mapping));
+ N_mapping =
+ OF_getprop(mmu, "translations", ofw_mapping, sizeof(ofw_mapping));
+ N_mapping /= sizeof(ofw_mapping[0]);
+
+ fw = &ofw_firmware;
+ fwcall = &fwentry;
+ return 0;
+}
+
+struct pmap ofw_pmap;
+int
+restore_ofw_mapping()
+{
+ int i;
+
+ pmap_pinit(&ofw_pmap);
+
+ ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
+
+ for (i = 0; i < N_mapping; i++) {
+ vm_offset_t pa = ofw_mapping[i].pa;
+ vm_offset_t va = ofw_mapping[i].va;
+ int size = ofw_mapping[i].len;
+
+ if (va < 0xf8000000) /* XXX */
+ continue;
+
+ while (size > 0) {
+ pmap_enter(&ofw_pmap, va, pa, VM_PROT_ALL, 1);
+ pa += NBPG;
+ va += NBPG;
+ size -= NBPG;
+ }
+ }
+
+ return 0;
}
#include <dev/ofw/openfirm.h>
@@ -257,9 +340,6 @@ ofwconprobe()
if (strcmp (name, "serial") == 0) {
ofwtrysercon (name, qhandle);
}
- if (strcmp (name, "pci") == 0) {
- ofwenablepcimemio (name, qhandle);
- }
}
if (phandle = OF_child(qhandle))
diff --git a/sys/arch/powerpc/powerpc/ofwreal.S b/sys/arch/powerpc/powerpc/ofwreal.S
index 8676bb53736..01fa1f42452 100644
--- a/sys/arch/powerpc/powerpc/ofwreal.S
+++ b/sys/arch/powerpc/powerpc/ofwreal.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofwreal.S,v 1.4 1997/10/13 13:42:59 pefo Exp $ */
+/* $OpenBSD: ofwreal.S,v 1.5 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $ */
/*
@@ -45,138 +45,128 @@
#include <machine/asm.h>
#include <machine/psl.h>
#include <machine/trap.h>
+#include <machine/param.h>
#define CACHELINE 32 /* Note that this value is really hardwired */
.data
ofentry: .long 0 /* actual entry to firmware in virtual mode */
-#define BATSIZE (8*8)
-#define SRSIZE (16*4)
+#define SRSIZE (16*4+4)
#define SPRGSIZE (4*4)
#define SDR1SIZE 4
-#define SI1SIZE (2*256)
-#define SI2SIZE (3*256)
-#define SVSIZE (BATSIZE+SRSIZE+SPRGSIZE+SDR1SIZE+SI1SIZE+SI2SIZE)
+#define MSRSIZE 4
+#define SVSIZE (SRSIZE+SPRGSIZE+SDR1SIZE+MSRSIZE)
+#define BATSIZE (16*4)
+
+ .global _C_LABEL(fwcall)
+_C_LABEL(fwcall): .long 0
.lcomm fwsave,SVSIZE,8
+.lcomm fwbatsave,BATSIZE,8
.lcomm clsave,SVSIZE,8
-
-_ENTRY(_C_LABEL(ofwr_init))
+.lcomm clbatsave,BATSIZE,8
+.lcomm ofsrsave,16*4,4 /* 16 words of 4 bytes to store OF segment registers */
+.lcomm srsave,16*4,4 /* 16 words of 4 bytes to swap OF segment registers*/
+ .globl _C_LABEL(ofmsr)
+_C_LABEL(ofmsr): .long 0 /* area to store msr for openfirmware*/
+
+ .text
+_ENTRY(_C_LABEL(ofw_init))
mflr 31 /* save return address */
mr 13,6 /* save args (only pointer used) */
lis 8,ofentry@ha
stw 5,ofentry@l(8) /* save virtual mode firmware entry */
- lis 3,fwsave@ha /* save the mmu values of the firmware */
+ lis 4,fwcall@ha /* call ofw directly until vm setup */
+ stw 5,fwcall@l(4)
+
+ mfmsr 5
+ lis 4,_C_LABEL(ofmsr)@ha /* save msr from openfirmware */
+ stw 5,_C_LABEL(ofmsr)@l(4)
+#if 0
+ lis 0,(0x80001ffe)@ha
+ addi 0,0,(0x80001ffe)@l
+ mtdbatu 0,0
+ lis 0,(0x80000022)@ha
+ addi 0,0,(0x80000022)@l
+ mtdbatl 0,0
+#endif
+
+ lis 3,fwsave@ha /* save the mmu values of the firmware */
addi 3,3,fwsave@l
+ lis 4,fwbatsave@ha
+ addi 4,4,fwbatsave@l
bl savemmu
- lis 5,fwentry@ha /* get new firmware entry */
- addi 5,5,fwentry@l
+ /* save openfirmware address mappings */
+ bl _C_LABEL(save_ofw_mapping)
+
+#if 0
+ /* dont really need the bats from firmware saved, 0 to disable */
+ lis 3,fwbatsave@ha
+ addi 3,3,fwbatsave@l
+ li 4,64
+ li 5,0
+1: subi 4,4,4
+ stwx 5,4,3
+ cmpi 4,0,0
+ bne 1b
+#endif
mr 6,13 /* restore args pointer */
mtlr 31 /* restore return address */
blr
/*
- * Emulated firmware entry.
- */
-fwentry:
- mflr 0 /* save return address */
- stw 0,4(1)
- stwu 1,-16(1) /* setup stack frame */
- stw 3,8(1) /* save arg */
-
- lis 3,clsave@ha /* save mmu values of client */
- addi 3,3,clsave@l
- bl savemmu
-
- lis 3,fwsave@ha /* restore mmu values of firmware */
- addi 3,3,fwsave@l
- bl restoremmu
-
- lis 3,ofentry@ha
- lwz 3,ofentry@l(3) /* get actual firmware entry */
- mtlr 3
-
- mfmsr 4
- ori 4,4,PSL_IR|PSL_DR /* turn on MMU */
- mtmsr 4
- isync
-
- lwz 3,8(1) /* restore arg */
- blrl /* do actual firmware call */
-
- stw 3,8(1) /* save return value */
-
- mfmsr 4
- lis 3,(PSL_IR|PSL_DR)@h /* turn off MMU */
- ori 3,3,(PSL_IR|PSL_DR)@l /* turn off MMU */
- andc 4,4,3 /* turn off MMU */
- mtmsr 4
- isync
-
- lis 3,fwsave@ha /* save mmu values of firmare */
- addi 3,3,fwsave@l /* (might not be necessary, but... */
- bl savemmu
-
- lis 3,clsave@ha /* restore mmu values of client */
- addi 3,3,clsave@l
- bl restoremmu
-
- lwz 3,8(1) /* restore return value */
- lwz 1,0(1) /* and return */
- lwz 0,4(1)
- mtlr 0
- blr
-
-/*
* Save everyting related to the mmu to the saveare pointed to by r3.
*/
+ .type savemmu,@function
savemmu:
+ mr 6,4 /* r4 holds pointer to BAT save area */
+
+ li 4,0 /* save SRs */
+1:
+ addis 4,4,-0x10000000@ha
+ or. 4,4,4
+ mfsrin 5,4
+ stwu 5,4(3)
+ bne 1b
+
mfibatl 4,0 /* save BATs */
- stw 4,0(3)
+ stw 4,0(6)
mfibatu 4,0
- stw 4,4(3)
+ stw 4,4(6)
mfibatl 4,1
- stw 4,8(3)
+ stw 4,8(6)
mfibatu 4,1
- stw 4,12(3)
+ stw 4,0xc(6)
mfibatl 4,2
- stw 4,16(3)
+ stw 4,0x10(6)
mfibatu 4,2
- stw 4,20(3)
+ stw 4,0x14(6)
mfibatl 4,3
- stw 4,24(3)
+ stw 4,0x18(6)
mfibatu 4,3
- stw 4,28(3)
+ stw 4,0x1c(6)
mfdbatl 4,0
- stw 4,32(3)
+ stw 4,0x20(6)
mfdbatu 4,0
- stw 4,36(3)
+ stw 4,0x24(6)
mfdbatl 4,1
- stw 4,40(3)
+ stw 4,0x28(6)
mfdbatu 4,1
- stw 4,44(3)
+ stw 4,0x2c(6)
mfdbatl 4,2
- stw 4,48(3)
+ stw 4,0x30(6)
mfdbatu 4,2
- stw 4,52(3)
+ stw 4,0x34(6)
mfdbatl 4,3
- stw 4,56(3)
+ stw 4,0x38(6)
mfdbatu 4,3
- stwu 4,60(3)
-
- li 4,0 /* save SRs */
-1:
- addis 4,4,-0x10000000@ha
- or. 4,4,4
- mfsrin 5,4
- stwu 5,4(3)
- bne 1b
+ stw 4,0x3c(6)
mfsprg 4,0 /* save SPRGs */
stw 4,4(3)
@@ -191,43 +181,9 @@ savemmu:
stw 4,20(3)
addi 4,3,24
- mflr 11
- li 3,EXC_DSI /* save DSI/ISI trap vectors */
- li 5,SI1SIZE
- bl copy
-
- mtlr 11
- li 3,EXC_IMISS /* save MISS trap vectors */
- li 5,SI2SIZE
-copy:
- li 6,CACHELINE
-1:
- lwz 7,0(3)
- lwz 8,4(3)
- lwz 9,8(3)
- lwz 10,12(3)
- stw 7,0(4)
- stw 8,4(4)
- stw 9,8(4)
- stw 10,12(4)
- lwz 7,16(3)
- lwz 8,20(3)
- lwz 9,24(3)
- lwz 10,28(3)
- stw 7,16(4)
- stw 8,20(4)
- stw 9,24(4)
- stw 10,28(4)
- dcbst 0,4
- icbi 0,4
- add 3,3,6
- add 4,4,6
- subf. 5,6,5
- bgt 1b
-
- dcbst 0,4
- icbi 0,4
+ mfmsr 4
+ stw 4,24(3)
sync
isync
@@ -235,10 +191,30 @@ copy:
blr
/*
- * Restore everyting related to the mmu from the saveare pointed to by r3.
+ * Restore everyting related to the mmu from the savearea pointed to by r3.
+ * and bats pointed to by r4.
*/
+ .type restoremmu,@function
restoremmu:
+ li 0,0
+ mtmsr 0
+ mr 6,4 /* pointer to sr to restore */
+ li 4,0 /* restore SRs */
+1:
+ lwzu 5,4(3)
+ addis 4,4,-0x10000000@ha
+ or. 4,4,4
+ mtsrin 5,4
+ bne 1b
+
+ mfmsr 4
+ lis 5,(PSL_IR|PSL_DR)@h /* turn off MMU */
+ ori 5,5,(PSL_IR|PSL_DR)@l /* turn off MMU */
+ andc 4,4,5 /* turn off MMU */
+ mtmsr 4
+ isync
+
li 4,0 /* first, invalidate BATs */
mtibatu 0,4
mtibatu 1,4
@@ -249,47 +225,39 @@ restoremmu:
mtdbatu 2,4
mtdbatu 3,4
- lwz 4,0(3)
+ lwz 4,0(6)
mtibatl 0,4 /* restore BATs */
- lwz 4,4(3)
+ lwz 4,4(6)
mtibatu 0,4
- lwz 4,8(3)
+ lwz 4,8(6)
mtibatl 1,4
- lwz 4,12(3)
+ lwz 4,12(6)
mtibatu 1,4
- lwz 4,16(3)
+ lwz 4,16(6)
mtibatl 2,4
- lwz 4,20(3)
+ lwz 4,20(6)
mtibatu 2,4
- lwz 4,24(3)
+ lwz 4,24(6)
mtibatl 3,4
- lwz 4,28(3)
+ lwz 4,28(6)
mtibatu 3,4
- lwz 4,32(3)
+ lwz 4,32(6)
mtdbatl 0,4
- lwz 4,36(3)
+ lwz 4,36(6)
mtdbatu 0,4
- lwz 4,40(3)
+ lwz 4,40(6)
mtdbatl 1,4
- lwz 4,44(3)
+ lwz 4,44(6)
mtdbatu 1,4
- lwz 4,48(3)
+ lwz 4,48(6)
mtdbatl 2,4
- lwz 4,52(3)
+ lwz 4,52(6)
mtdbatu 2,4
- lwz 4,56(3)
+ lwz 4,56(6)
mtdbatl 3,4
- lwzu 4,60(3)
+ lwz 4,60(6)
mtdbatu 3,4
- li 4,0 /* restore SRs */
-1:
- lwzu 5,4(3)
- addis 4,4,-0x10000000@ha
- or. 4,4,4
- mtsrin 5,4
- bne 1b
-
lwz 4,4(3)
mtsprg 0,4 /* restore SPRGs */
lwz 4,8(3)
@@ -315,20 +283,11 @@ restoremmu:
sync
mtsdr1 4 /* restore SDR1 */
- addi 3,3,24
- mflr 11
- li 4,EXC_DSI /* restore DSI/ISI trap vectors */
- li 5,SI1SIZE
- bl copy
-
- li 4,EXC_IMISS /* restore MISS trap vectors */
- li 5,SI2SIZE
- bl copy
/* tlbia */
sync
- li 3,0x40
- mtctr 3
+ li 5,0x40
+ mtctr 5
li 4,0
1:
tlbie 4
@@ -338,5 +297,154 @@ restoremmu:
tlbsync
sync
- mtlr 11
+ lwz 4,24(3)
+ mtmsr 4
+ isync
+
+ blr
+
+
+_ENTRY(_C_LABEL(fwentry))
+ stwu 1,-16(1)
+ mflr 4
+ stw 4,20(1)
+ stw 3,12(1) /* save arg */
+
+ lis 3,clsave@ha /* save mmu values of client */
+ addi 3,3,clsave@l
+ lis 4,clbatsave@ha /* save mmu values of client */
+ addi 4,4,clbatsave@l
+ bl savemmu
+
+ lis 3,fwsave@ha /* restore mmu values of firmware */
+ addi 3,3,fwsave@l
+ lis 4,fwbatsave@ha
+ addi 4,4,fwbatsave@l
+ bl restoremmu
+
+ lis 3,ofentry@ha
+ lwz 3,ofentry@l(3) /* get actual firmware entry */
+ mtlr 3
+
+ mfmsr 4
+ ori 4,4,PSL_IR|PSL_DR /* turn on MMU */
+ mtmsr 4
+ isync
+
+ lwz 3,12(1) /* restore arg */
+ blrl /* do actual firmware call */
+
+ stw 3,12(1) /* save return value */
+
+ lis 3,fwsave@ha /* save mmu values of firmare */
+ addi 3,3,fwsave@l /* (might not be necessary, but... */
+ lis 4,fwbatsave@ha
+ addi 4,4,fwbatsave@l
+ bl savemmu
+
+ lis 3,clsave@ha /* restore mmu values of client */
+ addi 3,3,clsave@l
+ lis 4,clbatsave@ha /* save mmu values of client */
+ addi 4,4,clbatsave@l
+ bl restoremmu
+
+ lwz 4,20(1)
+ lwz 3,12(1) /* restore return value */
+
+ mtlr 4
+ addi 1,1,16
+ blr
+
+/*
+ * OpenFirmware entry point
+ */
+_ENTRY(_C_LABEL(openfirmware))
+ stwu 1,-16(1)
+ mflr 0 /* save return address */
+ stw 0,20(1)
+
+ lis 4,fwcall@ha
+ lwz 4,fwcall@l(4)
+
+ mtlr 4
+ blrl
+
+ lwz 0,20(1)
+ mtlr 0
+ lwz 1,0(1)
blr
+
+/*
+ * Switch to/from OpenFirmware real mode stack
+ *
+ * Note: has to be called as the very first thing in OpenFirmware interface routines.
+ * E.g.:
+ * int
+ * OF_xxx(arg1, arg2)
+ * type arg1, arg2;
+ * {
+ * static struct {
+ * char *name;
+ * int nargs;
+ * int nreturns;
+ * char *method;
+ * int arg1;
+ * int arg2;
+ * int ret;
+ * } args = {
+ * "xxx",
+ * 2,
+ * 1,
+ * };
+ *
+ * ofw_stack();
+ * args.arg1 = arg1;
+ * args.arg2 = arg2;
+ * if (openfirmware(&args) < 0)
+ * return -1;
+ * return args.ret;
+ * }
+ */
+.lcomm firmstk,NBPG,16
+.comm _C_LABEL(OF_buf),NBPG,PGOFSET
+
+_ENTRY(_C_LABEL(ofw_stack))
+ mfmsr 8 /* turn off interrupts */
+ andi. 0,8,~(PSL_EE|PSL_RI)@l
+ mtmsr 0
+ stw 8,4(1) /* abuse return address slot */
+
+ lwz 5,0(1) /* get length of stack frame */
+ subf 5,1,5
+
+ lis 7,firmstk+NBPG-8@ha
+ addi 7,7,firmstk+NBPG-8@l
+ li 6,0xf
+ andc 7,7,6
+ lis 6,ofw_back@ha
+ addi 6,6,ofw_back@l
+ subf 4,5,7 /* make room for stack frame on new stack */
+ stwu 1,-16(7)
+ stw 6,4(7) /* setup return pointer */
+
+ stw 7,-16(4)
+
+ addi 3,1,8
+ addi 1,4,-16
+ subi 5,5,8
+ subi 4,4,8
+
+ b _C_LABEL(ofbcopy) /* and copy it */
+
+ .type ofw_back,@function
+ofw_back:
+ lwz 1,0(1) /* get callers original stack pointer */
+
+ lwz 0,4(1) /* get saved msr from abused slot */
+ mtmsr 0
+
+ lwz 1,0(1) /* return */
+ lwz 0,4(1)
+ mtlr 0
+ blr
+
diff --git a/sys/arch/powerpc/powerpc/opendev.c b/sys/arch/powerpc/powerpc/opendev.c
index c82812e7eb2..3c745b9d05c 100644
--- a/sys/arch/powerpc/powerpc/opendev.c
+++ b/sys/arch/powerpc/powerpc/opendev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opendev.c,v 1.1 1998/05/29 04:15:41 rahnds Exp $ */
+/* $OpenBSD: opendev.c,v 1.2 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */
/*
@@ -38,7 +38,7 @@
#include <dev/ofw/openfirm.h>
-char *OF_buf;
+extern char OF_buf[];
extern void ofw_stack __P((void));
extern void ofbcopy __P((const void *, void *, size_t));
diff --git a/sys/arch/powerpc/powerpc/openfirm.c b/sys/arch/powerpc/powerpc/openfirm.c
index c80ffe7fcd0..35404b377fa 100644
--- a/sys/arch/powerpc/powerpc/openfirm.c
+++ b/sys/arch/powerpc/powerpc/openfirm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: openfirm.c,v 1.3 1997/10/13 13:43:00 pefo Exp $ */
+/* $OpenBSD: openfirm.c,v 1.4 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */
/*
@@ -38,7 +38,7 @@
/*#include <dev/ofw/openfirm.h>*/
-char *OF_buf;
+extern char OF_buf[];
extern void ofw_stack __P((void));
extern void ofbcopy __P((const void *, void *, size_t));
@@ -193,7 +193,8 @@ OF_boot(bootspec)
ofbcopy(bootspec, OF_buf, l + 1);
args.bootspec = OF_buf;
openfirmware(&args);
- panic ("OF_boot returned!"); /* just in case */
+ printf ("OF_boot returned!"); /* just in case */
+ while (1);
}
void
diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c
index 5e3083b880d..0f69dbe758a 100644
--- a/sys/arch/powerpc/powerpc/pmap.c
+++ b/sys/arch/powerpc/powerpc/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.9 1999/03/22 02:41:21 rahnds Exp $ */
+/* $OpenBSD: pmap.c,v 1.10 1999/07/05 20:56:26 rahnds Exp $ */
/* $NetBSD: pmap.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */
/*
@@ -289,7 +289,7 @@ pmap_bootstrap(kernelstart, kernelend)
/*
* Get memory.
*/
- mem_regions(&mem, &avail);
+ (fw->mem_regions)(&mem, &avail);
for (mp = mem; mp->size; mp++)
physmem += btoc(mp->size);
@@ -367,13 +367,29 @@ pmap_bootstrap(kernelstart, kernelend)
mp1->size = sz;
}
}
+#if 0
avail_start = 0;
avail_end = npgs * NBPG;
+#endif
+
+#ifdef HTABENTS
+ ptab_cnt = HTABENTS;
+#else /* HTABENTS */
+ ptab_cnt = 1024;
+ while ((HTABSIZE << 7) < ctob(physmem))
+ ptab_cnt <<= 1;
+#endif /* HTABENTS */
+
/*
* Find suitably aligned memory for HTAB.
*/
for (mp = avail; mp->size; mp++) {
- s = mp->size % HTABSIZE;
+ s = mp->start % HTABSIZE;
+ if (mp->start % HTABSIZE == 0) {
+ s = 0;
+ } else {
+ s = HTABSIZE - (mp->start % HTABSIZE) ;
+ }
if (mp->size < s + HTABSIZE)
continue;
ptable = (pte_t *)(mp->start + s);