svn commit: r195901 - in projects/ppc64/sys/powerpc: aim aim64
include ofw
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Mon Jul 27 04:41:05 UTC 2009
Author: nwhitehorn
Date: Mon Jul 27 04:41:04 2009
New Revision: 195901
URL: http://svn.freebsd.org/changeset/base/195901
Log:
Add the various OFW machdep bits to be able to talk to a 32-bit Open
Firmware from a 64-bit environment, and also to handle calling locations
in memory from C. This involved hacking a PPC64 ABI function descriptor
structure to wrap the plain pointer to the OFW entry point.
With this, the kernel starts, prints Hello World, starts KDB, informs me
it has no platform module because the Mambo support is uncommitted,
politely panics, and stops. Huzzah!
Modified:
projects/ppc64/sys/powerpc/aim/ofw_machdep.c
projects/ppc64/sys/powerpc/aim64/locore.S
projects/ppc64/sys/powerpc/include/psl.h
projects/ppc64/sys/powerpc/ofw/ofw_real.c
Modified: projects/ppc64/sys/powerpc/aim/ofw_machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/ofw_machdep.c Sun Jul 26 20:52:12 2009 (r195900)
+++ projects/ppc64/sys/powerpc/aim/ofw_machdep.c Mon Jul 27 04:41:04 2009 (r195901)
@@ -74,6 +74,16 @@ static int (*ofwcall)(void *);
static void *fdt;
int ofw_real_mode;
+#ifdef __powerpc64__
+/* Handle PPC64 ABI brain damage */
+struct {
+ int (*funcptr)(void *);
+ uintptr_t toc;
+ uintptr_t env;
+} ofwcall_funcdesc;
+#endif
+
+
static int openfirmware(void *args);
/*
@@ -271,7 +281,18 @@ OF_initial_setup(void *fdt_ptr, void *ju
else
ofw_real_mode = 1;
- ofwcall = openfirm;
+ #ifdef __powerpc64__
+ /*
+ * For PPC64, we need to hack up a function descriptor object
+ * to be able to call a memory address.
+ */
+ ofwcall_funcdesc.funcptr = openfirm;
+ ofwcall_funcdesc.toc = 0;
+ ofwcall_funcdesc.env= 0;
+ ofwcall = (int (*)(void *))(&ofwcall_funcdesc);
+ #else
+ ofwcall = openfirm;
+ #endif
fdt = fdt_ptr;
}
Modified: projects/ppc64/sys/powerpc/aim64/locore.S
==============================================================================
--- projects/ppc64/sys/powerpc/aim64/locore.S Sun Jul 26 20:52:12 2009 (r195900)
+++ projects/ppc64/sys/powerpc/aim64/locore.S Mon Jul 27 04:41:04 2009 (r195901)
@@ -144,7 +144,7 @@ ASENTRY(__start)
mr 21,7
lis 8,openfirmware_entry at ha
- stw 5,openfirmware_entry at l(8) /* save client interface handler */
+ std 5,openfirmware_entry at l(8) /* save client interface handler */
lis 1,(tmpstk+TMPSTKSZ-16)@ha
addi 1,1,(tmpstk+TMPSTKSZ-16)@l
Modified: projects/ppc64/sys/powerpc/include/psl.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/psl.h Sun Jul 26 20:52:12 2009 (r195900)
+++ projects/ppc64/sys/powerpc/include/psl.h Mon Jul 27 04:41:04 2009 (r195901)
@@ -92,6 +92,10 @@
#define PSL_RI 0x00000002 /* recoverable interrupt */
#define PSL_LE 0x00000001 /* endian mode (1 == le) */
+#ifdef __powerpc64__
+#define PSL_SF (0x1UL << 63)
+#endif
+
#define PSL_601_MASK ~(PSL_POW|PSL_ILE|PSL_BE|PSL_RI|PSL_LE)
/*
@@ -109,7 +113,11 @@
#define PSL_MBO 0
#define PSL_MBZ 0
+#ifdef __powerpc64__
+#define PSL_KERNSET (PSL_SF | PSL_EE | PSL_ME | PSL_IR | PSL_DR | PSL_RI)
+#else
#define PSL_KERNSET (PSL_EE | PSL_ME | PSL_IR | PSL_DR | PSL_RI)
+#endif
#define PSL_USERSET (PSL_KERNSET | PSL_PR)
#define PSL_USERSTATIC (PSL_USERSET | PSL_IP | 0x87c0008c)
Modified: projects/ppc64/sys/powerpc/ofw/ofw_real.c
==============================================================================
--- projects/ppc64/sys/powerpc/ofw/ofw_real.c Sun Jul 26 20:52:12 2009 (r195900)
+++ projects/ppc64/sys/powerpc/ofw/ofw_real.c Mon Jul 27 04:41:04 2009 (r195901)
@@ -211,8 +211,13 @@ ofw_real_map(const void *buf, size_t len
mtx_assert(&of_bounce_mtx, MA_OWNED);
if (of_bounce_virt == NULL) {
+ /*
+ * If we haven't set up the MMU, then buf is guaranteed
+ * to be accessible to OF, because the only memory we
+ * can use right now is memory mapped by firmware.
+ */
if (!pmap_bootstrapped)
- return (cell_t)buf;
+ return (cell_t)(uintptr_t)buf;
/*
* XXX: It is possible for us to get called before the VM has
@@ -279,11 +284,11 @@ ofw_real_test(ofw_t ofw, const char *nam
cell_t nreturns;
cell_t service;
cell_t missing;
- } args = {
- (cell_t)"test",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"test";
+ args.nargs = 1;
+ args.nreturns = 1;
ofw_real_start();
@@ -310,11 +315,11 @@ ofw_real_peer(ofw_t ofw, phandle_t node)
cell_t nreturns;
cell_t node;
cell_t next;
- } args = {
- (cell_t)"peer",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"peer";
+ args.nargs = 1;
+ args.nreturns = 1;
args.node = node;
if (openfirmware(&args) == -1)
@@ -332,11 +337,11 @@ ofw_real_child(ofw_t ofw, phandle_t node
cell_t nreturns;
cell_t node;
cell_t child;
- } args = {
- (cell_t)"child",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"child";
+ args.nargs = 1;
+ args.nreturns = 1;
args.node = node;
if (openfirmware(&args) == -1)
@@ -354,11 +359,11 @@ ofw_real_parent(ofw_t ofw, phandle_t nod
cell_t nreturns;
cell_t node;
cell_t parent;
- } args = {
- (cell_t)"parent",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"parent";
+ args.nargs = 1;
+ args.nreturns = 1;
args.node = node;
if (openfirmware(&args) == -1)
@@ -376,11 +381,11 @@ ofw_real_instance_to_package(ofw_t ofw,
cell_t nreturns;
cell_t instance;
cell_t package;
- } args = {
- (cell_t)"instance-to-package",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"instance-to-package";
+ args.nargs = 1;
+ args.nreturns = 1;
args.instance = instance;
if (openfirmware(&args) == -1)
@@ -399,11 +404,11 @@ ofw_real_getproplen(ofw_t ofw, phandle_t
cell_t package;
cell_t propname;
cell_t proplen;
- } args = {
- (cell_t)"getproplen",
- 2,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"getproplen";
+ args.nargs = 2;
+ args.nreturns = 1;
ofw_real_start();
@@ -431,11 +436,11 @@ ofw_real_getprop(ofw_t ofw, phandle_t pa
cell_t buf;
cell_t buflen;
cell_t size;
- } args = {
- (cell_t)"getprop",
- 4,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"getprop";
+ args.nargs = 4;
+ args.nreturns = 1;
ofw_real_start();
@@ -466,11 +471,11 @@ ofw_real_nextprop(ofw_t ofw, phandle_t p
cell_t previous;
cell_t buf;
cell_t flag;
- } args = {
- (cell_t)"nextprop",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"nextprop";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -502,11 +507,11 @@ ofw_real_setprop(ofw_t ofw, phandle_t pa
cell_t buf;
cell_t len;
cell_t size;
- } args = {
- (cell_t)"setprop",
- 4,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"setprop";
+ args.nargs = 4;
+ args.nreturns = 1;
ofw_real_start();
@@ -534,11 +539,11 @@ ofw_real_canon(ofw_t ofw, const char *de
cell_t buf;
cell_t len;
cell_t size;
- } args = {
- (cell_t)"canon",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"canon";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -565,11 +570,11 @@ ofw_real_finddevice(ofw_t ofw, const cha
cell_t nreturns;
cell_t device;
cell_t package;
- } args = {
- (cell_t)"finddevice",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"finddevice";
+ args.nargs = 1;
+ args.nreturns = 1;
ofw_real_start();
@@ -594,11 +599,11 @@ ofw_real_instance_to_path(ofw_t ofw, iha
cell_t buf;
cell_t len;
cell_t size;
- } args = {
- (cell_t)"instance-to-path",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"instance-to-path";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -627,11 +632,11 @@ ofw_real_package_to_path(ofw_t ofw, phan
cell_t buf;
cell_t len;
cell_t size;
- } args = {
- (cell_t)"package-to-path",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"package-to-path";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -660,15 +665,15 @@ ofw_real_call_method(ofw_t ofw, ihandle_
cell_t method;
cell_t instance;
cell_t args_n_results[12];
- } args = {
- (cell_t)"call-method",
- 2,
- 1,
- };
+ } args;
cell_t *cp;
unsigned long *ap;
int n;
+ args.name = (cell_t)(uintptr_t)"call-method";
+ args.nargs = 2;
+ args.nreturns = 1;
+
if (nargs > 6)
return (-1);
@@ -707,11 +712,11 @@ ofw_real_open(ofw_t ofw, const char *dev
cell_t nreturns;
cell_t device;
cell_t instance;
- } args = {
- (cell_t)"open",
- 1,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"open";
+ args.nargs = 1;
+ args.nreturns = 1;
ofw_real_start();
@@ -734,10 +739,10 @@ ofw_real_close(ofw_t ofw, ihandle_t inst
cell_t nargs;
cell_t nreturns;
cell_t instance;
- } args = {
- (cell_t)"close",
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"close";
+ args.nargs = 1;
args.instance = instance;
openfirmware(&args);
@@ -755,11 +760,11 @@ ofw_real_read(ofw_t ofw, ihandle_t insta
cell_t addr;
cell_t len;
cell_t actual;
- } args = {
- (cell_t)"read",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"read";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -788,11 +793,11 @@ ofw_real_write(ofw_t ofw, ihandle_t inst
cell_t addr;
cell_t len;
cell_t actual;
- } args = {
- (cell_t)"write",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"write";
+ args.nargs = 3;
+ args.nreturns = 1;
ofw_real_start();
@@ -819,11 +824,11 @@ ofw_real_seek(ofw_t ofw, ihandle_t insta
cell_t poshi;
cell_t poslo;
cell_t status;
- } args = {
- (cell_t)"seek",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"seek";
+ args.nargs = 3;
+ args.nreturns = 1;
args.instance = instance;
args.poshi = pos >> 32;
@@ -849,18 +854,18 @@ ofw_real_claim(ofw_t ofw, void *virt, si
cell_t size;
cell_t align;
cell_t baseaddr;
- } args = {
- (cell_t)"claim",
- 3,
- 1,
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"claim";
+ args.nargs = 3;
+ args.nreturns = 1;
- args.virt = (cell_t)virt;
+ args.virt = (cell_t)(uintptr_t)virt;
args.size = size;
args.align = align;
if (openfirmware(&args) == -1)
return ((void *)-1);
- return ((void *)args.baseaddr);
+ return ((void *)(uintptr_t)args.baseaddr);
}
/* Release an area of memory. */
@@ -873,12 +878,12 @@ ofw_real_release(ofw_t ofw, void *virt,
cell_t nreturns;
cell_t virt;
cell_t size;
- } args = {
- (cell_t)"release",
- 2,
- };
+ } args;
- args.virt = (cell_t)virt;
+ args.name = (cell_t)(uintptr_t)"release";
+ args.nargs = 2;
+
+ args.virt = (cell_t)(uintptr_t)virt;
args.size = size;
openfirmware(&args);
}
@@ -895,9 +900,9 @@ ofw_real_enter(ofw_t ofw)
cell_t name;
cell_t nargs;
cell_t nreturns;
- } args = {
- (cell_t)"enter",
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"enter";
openfirmware(&args);
/* We may come back. */
@@ -911,9 +916,9 @@ ofw_real_exit(ofw_t ofw)
cell_t name;
cell_t nargs;
cell_t nreturns;
- } args = {
- (cell_t)"exit",
- };
+ } args;
+
+ args.name = (cell_t)(uintptr_t)"exit";
openfirmware(&args);
for (;;) /* just in case */
More information about the svn-src-projects
mailing list