summaryrefslogtreecommitdiff
path: root/sys/arch/macppc/stand/Locore.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/macppc/stand/Locore.c')
-rw-r--r--sys/arch/macppc/stand/Locore.c593
1 files changed, 593 insertions, 0 deletions
diff --git a/sys/arch/macppc/stand/Locore.c b/sys/arch/macppc/stand/Locore.c
new file mode 100644
index 00000000000..e43d875d36c
--- /dev/null
+++ b/sys/arch/macppc/stand/Locore.c
@@ -0,0 +1,593 @@
+/* $OpenBSD: Locore.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */
+/* $NetBSD: Locore.c,v 1.1 1997/04/16 20:29:11 thorpej Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <lib/libsa/stand.h>
+#include <macppc/stand/openfirm.h>
+
+/*
+#include "machine/cpu.h"
+*/
+
+static int (*openfirmware)(void *);
+
+static void setup __P((void));
+
+#ifdef XCOFF_GLUE
+asm (".text; .globl _entry; _entry: .long _start,0,0");
+#endif
+asm("
+ .text
+ .globl bat_init
+bat_init:
+
+ mfmsr 8
+ li 0,0
+ mtmsr 0
+ isync
+
+ mtibatu 0,0
+ mtibatu 1,0
+ mtibatu 2,0
+ mtibatu 3,0
+ mtdbatu 0,0
+ mtdbatu 1,0
+ mtdbatu 2,0
+ mtdbatu 3,0
+
+ li 9,0x12 /* BATL(0, BAT_M, BAT_PP_RW) */
+ mtibatl 0,9
+ mtdbatl 0,9
+ li 9,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */
+ mtibatu 0,9
+ mtdbatu 0,9
+ isync
+
+ mtmsr 8
+ isync
+ blr
+");
+
+__dead void
+_start(vpd, res, openfirm, arg, argl)
+ void *vpd;
+ int res;
+ int (*openfirm)(void *);
+ char *arg;
+ int argl;
+{
+ extern char etext[];
+
+#ifdef FIRMWORKSBUGS
+ syncicache((void *)RELOC, etext - (char *)RELOC);
+#endif
+ bat_init();
+ openfirmware = openfirm; /* Save entry to Open Firmware */
+#if 0
+ patch_dec_intr();
+#endif
+ setup();
+ main(arg, argl);
+ exit();
+}
+
+#if 0
+void handle_decr_intr();
+__asm ( " .globl handle_decr_intr\n"
+ " .type handle_decr_intr@function\n"
+ "handle_decr_intr:\n"
+ " rfi\n");
+
+
+patch_dec_intr()
+{
+ int time;
+ unsigned int *decr_intr = (unsigned int *)0x900;
+ unsigned int br_instr;
+
+ /* this hack is to prevent unexected Decrementer Exceptions
+ * when Apple openfirmware enables interrupts
+ */
+ time = 0x40000000;
+ asm("mtdec %0" :: "r"(time));
+ /* we assume that handle_decr_intr is in the first 128 Meg */
+ br_instr = (18 << 23) | (unsigned int)handle_decr_intr;
+ *decr_intr = br_instr;
+
+
+
+}
+#endif
+__dead void
+_rtt()
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ } args = {
+ "exit",
+ 0,
+ 0
+ };
+
+ openfirmware(&args);
+ while (1); /* just in case */
+}
+
+int
+OF_finddevice(name)
+ char *name;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ char *device;
+ int phandle;
+ } args = {
+ "finddevice",
+ 1,
+ 1,
+ };
+
+ args.device = name;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.phandle;
+}
+
+int
+OF_instance_to_package(ihandle)
+ int ihandle;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int ihandle;
+ int phandle;
+ } args = {
+ "instance-to-package",
+ 1,
+ 1,
+ };
+
+ args.ihandle = ihandle;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.phandle;
+}
+
+int
+OF_getprop(handle, prop, buf, buflen)
+ int handle;
+ char *prop;
+ void *buf;
+ int buflen;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int phandle;
+ char *prop;
+ void *buf;
+ int buflen;
+ int size;
+ } args = {
+ "getprop",
+ 4,
+ 1,
+ };
+
+ args.phandle = handle;
+ args.prop = prop;
+ args.buf = buf;
+ args.buflen = buflen;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.size;
+}
+
+#ifdef __notyet__ /* Has a bug on FirePower */
+int
+OF_setprop(handle, prop, buf, len)
+ int handle;
+ char *prop;
+ void *buf;
+ int len;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int phandle;
+ char *prop;
+ void *buf;
+ int len;
+ int size;
+ } args = {
+ "setprop",
+ 4,
+ 1,
+ };
+
+ args.phandle = handle;
+ args.prop = prop;
+ args.buf = buf;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.size;
+}
+#endif
+
+int
+OF_open(dname)
+ char *dname;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ char *dname;
+ int handle;
+ } args = {
+ "open",
+ 1,
+ 1,
+ };
+
+ args.dname = dname;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.handle;
+}
+
+void
+OF_close(handle)
+ int handle;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int handle;
+ } args = {
+ "close",
+ 1,
+ 0,
+ };
+
+ args.handle = handle;
+ openfirmware(&args);
+}
+
+int
+OF_write(handle, addr, len)
+ int handle;
+ void *addr;
+ int len;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args = {
+ "write",
+ 3,
+ 1,
+ };
+
+ args.ihandle = handle;
+ args.addr = addr;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.actual;
+}
+
+int
+OF_read(handle, addr, len)
+ int handle;
+ void *addr;
+ int len;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args = {
+ "read",
+ 3,
+ 1,
+ };
+
+ args.ihandle = handle;
+ args.addr = addr;
+ args.len = len;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.actual;
+}
+
+int
+OF_seek(handle, pos)
+ int handle;
+ u_quad_t pos;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int handle;
+ int poshi;
+ int poslo;
+ int status;
+ } args = {
+ "seek",
+ 3,
+ 1,
+ };
+
+ args.handle = handle;
+ args.poshi = (int)(pos >> 32);
+ args.poslo = (int)pos;
+ if (openfirmware(&args) == -1)
+ return -1;
+ return args.status;
+}
+
+void *
+OF_claim(virt, size, align)
+ void *virt;
+ u_int size;
+ u_int align;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ void *virt;
+ u_int size;
+ u_int align;
+ void *baseaddr;
+ } args = {
+ "claim",
+ 3,
+ 1,
+ };
+
+/*
+#ifdef FIRMWORKSBUGS
+*/
+#if 0
+ /*
+ * Bug with Firmworks OFW
+ */
+ if (virt)
+ return virt;
+#endif
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ if (openfirmware(&args) == -1)
+ return (void *)-1;
+ if (virt != 0) {
+ return virt;
+ }
+ return args.baseaddr;
+}
+
+void
+OF_release(virt, size)
+ void *virt;
+ u_int size;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ void *virt;
+ u_int size;
+ } args = {
+ "release",
+ 2,
+ 0,
+ };
+
+ args.virt = virt;
+ args.size = size;
+ openfirmware(&args);
+}
+
+int
+OF_milliseconds()
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ int ms;
+ } args = {
+ "milliseconds",
+ 0,
+ 1,
+ };
+
+ openfirmware(&args);
+ return args.ms;
+}
+
+#ifdef __notyet__
+void
+OF_chain(virt, size, entry, arg, len)
+ void *virt;
+ u_int size;
+ void (*entry)();
+ void *arg;
+ u_int len;
+{
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ void *virt;
+ u_int size;
+ void (*entry)();
+ void *arg;
+ u_int len;
+ } args = {
+ "chain",
+ 5,
+ 0,
+ };
+
+ args.virt = virt;
+ args.size = size;
+ args.entry = entry;
+ args.arg = arg;
+ args.len = len;
+ openfirmware(&args);
+}
+#else
+void
+OF_chain(virt, size, entry, arg, len)
+ void *virt;
+ u_int size;
+ void (*entry)();
+ void *arg;
+ u_int len;
+{
+ /*
+ * This is a REALLY dirty hack till the firmware gets this going
+ OF_release(virt, size);
+ */
+ entry(0, 0, openfirmware, arg, len);
+}
+#endif
+
+int
+#ifdef __STDC__
+OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
+#else
+OF_call_method(method, ihandle, nargs, nreturns, va_alist)
+ char *method;
+ int ihandle;
+ int nargs;
+ int nreturns;
+ va_dcl
+#endif
+{
+ va_list ap;
+ static struct {
+ char *name;
+ int nargs;
+ int nreturns;
+ char *method;
+ int ihandle;
+ int args_n_results[12];
+ } args = {
+ "call-method",
+ 2,
+ 1,
+ };
+ int *ip, n;
+
+ if (nargs > 6)
+ return -1;
+ args.nargs = nargs + 2;
+ args.nreturns = nreturns + 1;
+ args.method = method;
+ args.ihandle = ihandle;
+ va_start(ap, nreturns);
+ for (ip = args.args_n_results + (n = nargs); --n >= 0;)
+ *--ip = va_arg(ap, int);
+
+ if (openfirmware(&args) == -1)
+ return -1;
+ if (args.args_n_results[nargs])
+ return args.args_n_results[nargs];
+ for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
+ *va_arg(ap, int *) = *--ip;
+ va_end(ap);
+ return 0;
+}
+
+static int stdin;
+static int stdout;
+
+static void
+setup()
+{
+ int chosen;
+
+ if ((chosen = OF_finddevice("/chosen")) == -1)
+ _rtt();
+ if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
+ || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
+ sizeof(stdout))
+ _rtt();
+}
+
+void
+putchar(c)
+ int c;
+{
+ char ch = c;
+
+ if (c == '\n')
+ putchar('\r');
+ OF_write(stdout, &ch, 1);
+}
+
+int
+getchar()
+{
+ unsigned char ch = '\0';
+ int l;
+
+ while ((l = OF_read(stdin, &ch, 1)) != 1)
+ if (l != -2 && l != 0)
+ return -1;
+ return ch;
+}