summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2008-12-20 00:33:10 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2008-12-20 00:33:10 +0000
commit3fcef6d9c20b6c3577c741e4a0fe24807fd08a66 (patch)
tree25aa78cf699f4beb5681bc0e1e056803a5395bd5 /sys/powerpc
parentf1d5ce3d64d95a7fc58c2c93fd5f97f510a8f9ba (diff)
downloadFreeBSD-src-3fcef6d9c20b6c3577c741e4a0fe24807fd08a66.zip
FreeBSD-src-3fcef6d9c20b6c3577c741e4a0fe24807fd08a66.tar.gz
Modularize the Open Firmware client interface to allow run-time switching
of OFW access semantics, in order to allow future support for real-mode OF access and flattened device frees. OF client interface modules are implemented using KOBJ, in a similar way to the PPC PMAP modules. Because we need Open Firmware to be available before mutexes can be used on sparc64, changes are also included to allow KOBJ to be used very early in the boot process by only using the mutex once we know it has been initialized. Reviewed by: marius, grehan
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/locore.S11
-rw-r--r--sys/powerpc/aim/machdep.c12
-rw-r--r--sys/powerpc/aim/ofw_machdep.c47
-rw-r--r--sys/powerpc/booke/machdep.c1
-rw-r--r--sys/powerpc/include/ofw_machdep.h9
-rw-r--r--sys/powerpc/powerpc/pmap_dispatch.c5
6 files changed, 65 insertions, 20 deletions
diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S
index cfe75d9..60e5e9d 100644
--- a/sys/powerpc/aim/locore.S
+++ b/sys/powerpc/aim/locore.S
@@ -129,14 +129,6 @@ kernel_text:
.text
.globl __start
__start:
-#ifdef FIRMWORKSBUGS
- mfmsr 0
- andi. 0,0,PSL_IR|PSL_DR
- beq 1f
-
- bl ofwr_init
-1:
-#endif
li 8,0
li 9,0x100
mtctr 9
@@ -154,7 +146,6 @@ __start:
lis 8,openfirmware_entry@ha
stw 5,openfirmware_entry@l(8) /* save client interface handler */
- mr 3,5
lis 1,(tmpstk+TMPSTKSZ-16)@ha
addi 1,1,(tmpstk+TMPSTKSZ-16)@l
@@ -172,7 +163,7 @@ __start:
mfsprg3 0
stw 0,16(9) /* ofmsr[4] = sprg3 */
- bl OF_init
+ bl OF_initial_setup
lis 4,end@ha
addi 4,4,end@l
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index 13fc2a7..2199cb1 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -291,9 +291,19 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
__asm __volatile("mtsprg 0, %0" :: "r"(pc));
+ /*
+ * Init mutexes, which we use heavily in PMAP
+ */
+
mutex_init();
/*
+ * Install the OF client interface
+ */
+
+ OF_bootstrap();
+
+ /*
* Initialize the console before printing anything.
*/
cninit();
@@ -307,8 +317,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
kdb_init();
- kobj_machdep_init();
-
/*
* XXX: Initialize the interrupt tables.
* Disable translation in case the vector area
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index 2755819..0d5f03b 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -65,6 +65,10 @@ static struct mem_region OFfree[OFMEM_REGIONS + 3];
extern register_t ofmsr[5];
extern struct pmap ofw_pmap;
static int (*ofwcall)(void *);
+static void *fdt;
+int ofw_real_mode;
+
+static int openfirmware(void *args);
/*
* Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback.
@@ -192,13 +196,45 @@ mem_regions(struct mem_region **memp, int *memsz,
}
void
-set_openfirm_callback(int (*openfirm)(void *))
+OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *))
{
+ if (ofmsr[0] & PSL_DR)
+ ofw_real_mode = 0;
+ else
+ ofw_real_mode = 1;
ofwcall = openfirm;
+ fdt = fdt_ptr;
}
-int
+boolean_t
+OF_bootstrap()
+{
+ boolean_t status = FALSE;
+
+ if (ofwcall != NULL) {
+ if (ofw_real_mode)
+ status = OF_install(OFW_STD_REAL, 0);
+ else
+ status = OF_install(OFW_STD_DIRECT, 0);
+
+ if (status != TRUE)
+ return status;
+
+ OF_init(openfirmware);
+ } else {
+ status = OF_install(OFW_FDT, 0);
+
+ if (status != TRUE)
+ return status;
+
+ OF_init(fdt);
+ }
+
+ return (status);
+}
+
+static int
openfirmware(void *args)
{
long oldmsr;
@@ -206,6 +242,9 @@ openfirmware(void *args)
u_int srsave[16];
u_int i;
+ if (pmap_bootstrapped && ofw_real_mode)
+ args = (void *)pmap_kextract((vm_offset_t)args);
+
__asm __volatile( "\t"
"sync\n\t"
"mfmsr %0\n\t"
@@ -217,7 +256,7 @@ openfirmware(void *args)
ofw_sprg_prepare();
- if (pmap_bootstrapped) {
+ if (pmap_bootstrapped && !ofw_real_mode) {
/*
* Swap the kernel's address space with Open Firmware's
*/
@@ -236,7 +275,7 @@ openfirmware(void *args)
result = ofwcall(args);
- if (pmap_bootstrapped) {
+ if (pmap_bootstrapped && !ofw_real_mode) {
/*
* Restore the kernel's addr space. The isync() doesn;t
* work outside the loop unless mtsrin() is open-coded
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 85cc184..a48ece1 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -430,7 +430,6 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
- kobj_machdep_init();
/* Initialise virtual memory. */
pmap_mmu_install(MMU_TYPE_BOOKE, 0);
diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h
index a4b601e..1dd2027 100644
--- a/sys/powerpc/include/ofw_machdep.h
+++ b/sys/powerpc/include/ofw_machdep.h
@@ -28,9 +28,18 @@
#ifndef _MACHINE_OFW_MACHDEP_H_
#define _MACHINE_OFW_MACHDEP_H_
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/rman.h>
#include <sys/bus.h>
+#include <dev/ofw/openfirm.h>
+
+typedef uint32_t cell_t;
int OF_decode_addr(phandle_t, int, bus_space_tag_t *, bus_space_handle_t *);
void OF_getetheraddr(device_t dev, u_char *addr);
+void OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *));
+boolean_t OF_bootstrap(void);
+
#endif /* _MACHINE_OFW_MACHDEP_H_ */
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index 55112bb..33e94d1 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -37,9 +37,8 @@ __FBSDID("$FreeBSD$");
* the highest priority call will be installed as the default
* MMU handler when pmap_bootstrap() is called.
*
- * It is required that kobj_machdep_init() be called before
- * pmap_bootstrap() to allow the kobj subsystem to initialise. This
- * in turn requires that mutex_init() has been called.
+ * It is required that mutex_init() be called before pmap_bootstrap(),
+ * as the PMAP layer makes extensive use of mutexes.
*/
#include <sys/param.h>
OpenPOWER on IntegriCloud