summaryrefslogtreecommitdiff
path: root/sys/arch/mips
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>1998-01-28 12:12:10 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>1998-01-28 12:12:10 +0000
commitd2d2a72135a2801084e26a82991316e8a3f4afbf (patch)
tree99aff6458f5009611a9e4c476a54175bf9ae8085 /sys/arch/mips
parente132fd998366d8d693ef08f870464d6dafc9232b (diff)
First set of Mips mi files.
Diffstat (limited to 'sys/arch/mips')
-rw-r--r--sys/arch/mips/mips/arcbios.c332
-rw-r--r--sys/arch/mips/mips/clock.c360
-rw-r--r--sys/arch/mips/mips/cpu.c207
-rw-r--r--sys/arch/mips/mips/cpu_ecoff.c92
-rw-r--r--sys/arch/mips/mips/disksubr.c523
-rw-r--r--sys/arch/mips/mips/mainbus.c191
-rw-r--r--sys/arch/mips/mips/mem.c180
-rw-r--r--sys/arch/mips/mips/minidebug.c953
-rw-r--r--sys/arch/mips/mips/process_machdep.c116
-rw-r--r--sys/arch/mips/mips/sys_machdep.c130
10 files changed, 3084 insertions, 0 deletions
diff --git a/sys/arch/mips/mips/arcbios.c b/sys/arch/mips/mips/arcbios.c
new file mode 100644
index 00000000000..a359dd73dad
--- /dev/null
+++ b/sys/arch/mips/mips/arcbios.c
@@ -0,0 +1,332 @@
+/* $OpenBSD: arcbios.c,v 1.1 1998/01/28 12:12:06 pefo Exp $ */
+/*-
+ * Copyright (c) 1996 M. Warner Losh. All rights reserved.
+ * Copyright (c) 1996 Per Fogelstrom. 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. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <lib/libkern/libkern.h>
+#include <machine/pte.h>
+#include <machine/cpu.h>
+#include <machine/memconf.h>
+#include <machine/param.h>
+#include <mips/mips/arcbios.h>
+#include <mips/archtype.h>
+
+arc_param_blk_t *bios_base = ArcBiosBase;
+
+extern int system_type; /* Mother board type */
+extern int physmem; /* Total physical memory size */
+
+int Bios_Read __P((int, char *, int, int *));
+int Bios_Write __P((int, char *, int, int *));
+int Bios_Open __P((char *, int, u_int *));
+int Bios_Close __P((u_int));
+arc_mem_t *Bios_GetMemoryDescriptor __P((arc_mem_t *));
+arc_sid_t *Bios_GetSystemId __P((void));
+arc_config_t *Bios_GetChild __P((arc_config_t *));
+arc_dsp_stat_t *Bios_GetDisplayStatus __P((int));
+
+static void bios_configure_memory __P((void));
+static int get_system_type __P((void));
+
+char buf[100]; /*XXX*/
+arc_dsp_stat_t displayinfo; /* Save area for display status info. */
+
+static struct systypes {
+ char *sys_vend; /* Vendor ID if name is ambigous */
+ char *sys_name; /* May be left NULL if name is sufficient */
+ int sys_type;
+} sys_types[] = {
+ { NULL, "PICA-61", ACER_PICA_61 },
+ { NULL, "DESKTECH-TYNE", DESKSTATION_TYNE },
+ { NULL, "DESKTECH-ARCStation I", DESKSTATION_RPC44 },
+ { NULL, "Microsoft-Jazz", MAGNUM },
+ { NULL, "RM200PCI", SNI_RM200 },
+ { NULL, "SGI-IP22", SGI_INDY },
+};
+
+#define KNOWNSYSTEMS (sizeof(sys_types) / sizeof(struct systypes))
+
+/*
+ * ARC Bios trampoline code.
+ */
+#define ARC_Call(Name,Offset) \
+__asm__("\n" \
+" .text\n" \
+" .ent " #Name "\n" \
+" .align 3\n" \
+" .set noreorder\n" \
+" .globl " #Name "\n" \
+#Name":\n" \
+" lw $2, 0x80001020\n"\
+" lw $2," #Offset "($2)\n"\
+" jr $2\n" \
+" nop\n" \
+" .end " #Name "\n" );
+
+ARC_Call(Bios_Load, 0x00);
+ARC_Call(Bios_Invoke, 0x04);
+ARC_Call(Bios_Execute, 0x08);
+ARC_Call(Bios_Halt, 0x0c);
+ARC_Call(Bios_PowerDown, 0x10);
+ARC_Call(Bios_Restart, 0x14);
+ARC_Call(Bios_Reboot, 0x18);
+ARC_Call(Bios_EnterInteractiveMode, 0x1c);
+ARC_Call(Bios_Unused1, 0x20);
+ARC_Call(Bios_GetPeer, 0x24);
+ARC_Call(Bios_GetChild, 0x28);
+ARC_Call(Bios_GetParent, 0x2c);
+ARC_Call(Bios_GetConfigurationData, 0x30);
+ARC_Call(Bios_AddChild, 0x34);
+ARC_Call(Bios_DeleteComponent, 0x38);
+ARC_Call(Bios_GetComponent, 0x3c);
+ARC_Call(Bios_SaveConfiguration, 0x40);
+ARC_Call(Bios_GetSystemId, 0x44);
+ARC_Call(Bios_GetMemoryDescriptor, 0x48);
+ARC_Call(Bios_Unused2, 0x4c);
+ARC_Call(Bios_GetTime, 0x50);
+ARC_Call(Bios_GetRelativeTime, 0x54);
+ARC_Call(Bios_GetDirectoryEntry, 0x58);
+ARC_Call(Bios_Open, 0x5c);
+ARC_Call(Bios_Close, 0x60);
+ARC_Call(Bios_Read, 0x64);
+ARC_Call(Bios_GetReadStatus, 0x68);
+ARC_Call(Bios_Write, 0x6c);
+ARC_Call(Bios_Seek, 0x70);
+ARC_Call(Bios_Mount, 0x74);
+ARC_Call(Bios_GetEnvironmentVariable, 0x78);
+ARC_Call(Bios_SetEnvironmentVariable, 0x7c);
+ARC_Call(Bios_GetFileInformation, 0x80);
+ARC_Call(Bios_SetFileInformation, 0x84);
+ARC_Call(Bios_FlushAllCaches, 0x88);
+ARC_Call(Bios_TestUnicodeCharacter, 0x8c);
+ARC_Call(Bios_GetDisplayStatus, 0x90);
+
+/*
+ * Simple getchar/putchar interface.
+ */
+
+int
+bios_getchar()
+{
+ char buf[4];
+ int cnt;
+
+ if(Bios_Read(0, &buf[0], 1, &cnt) != 0)
+ return(-1);
+ return(buf[0] & 255);
+}
+
+void
+bios_putchar(c)
+char c;
+{
+ char buf[4];
+ int cnt;
+
+ if(c == '\n') {
+ buf[0] = '\r';
+ buf[1] = c;
+ cnt = 2;
+ if(displayinfo.CursorYPosition < displayinfo.CursorMaxYPosition)
+ displayinfo.CursorYPosition++;
+ }
+ else {
+ buf[0] = c;
+ cnt = 1;
+ }
+ Bios_Write(1, &buf[0], cnt, &cnt);
+}
+
+void
+bios_putstring(s)
+char *s;
+{
+ while(*s) {
+ bios_putchar(*s++);
+ }
+}
+
+/*
+ * Get memory descriptor for the memory configuration and
+ * create a layout database used by pmap init to set up
+ * the memory system. Note that kernel option "MACHINE_NONCONTIG"
+ * must be set for systems with non contigous physical memory.
+ *
+ * Concatenate obvious adjecent segments.
+ */
+static void
+bios_configure_memory()
+{
+ arc_mem_t *descr = 0;
+ struct mem_descriptor *m;
+ vm_offset_t seg_start, seg_end;
+ int i;
+
+ descr = (arc_mem_t *)Bios_GetMemoryDescriptor(descr);
+ while(descr != 0) {
+
+ seg_start = descr->BasePage * 4096;
+ seg_end = seg_start + descr->PageCount * 4096;
+
+ switch(descr->Type) {
+ case BadMemory: /* Have no use for theese */
+ break;
+
+#if 0
+ case ExeceptionBlock:
+ case SystemParameterBlock:
+ case FirmwareTemporary:
+ case FirmwarePermanent:
+#endif
+ case FreeMemory:
+ case FreeContigous:
+ physmem += descr->PageCount * 4096;
+ m = 0;
+ for( i = 0; i < MAXMEMSEGS; i++) {
+ if(mem_layout[i].mem_size == 0) {
+ if(m == 0)
+ m = &mem_layout[i]; /* free */
+ }
+ else if(seg_end == mem_layout[i].mem_start) {
+ m = &mem_layout[i];
+ m->mem_start = seg_start;
+ m->mem_size += seg_end - seg_start;
+ }
+ else if(mem_layout[i].mem_start +
+ mem_layout[i].mem_size == seg_start) {
+ m = &mem_layout[i];
+ m->mem_size += seg_end - seg_start;
+ }
+ }
+ if(m && m->mem_size == 0) {
+ m->mem_start = seg_start;
+ m->mem_size = seg_end - seg_start;
+ }
+ break;
+
+ case LoadedProgram: /* This is the loaded kernel */
+ physmem += descr->PageCount * 4096;
+ break;
+
+ default: /* Unknown type, leave it alone... */
+ break;
+ }
+ descr = (arc_mem_t *)Bios_GetMemoryDescriptor(descr);
+ }
+
+#if 0
+ for( i = 0; i < MAXMEMSEGS; i++) {
+ if(mem_layout[i].mem_size) {
+ sprintf(buf, "MEM %d, 0x%x, 0x%x\n",i,
+ mem_layout[i].mem_start,
+ mem_layout[i].mem_size);
+ bios_putstring(buf);
+ }
+ }
+#endif
+}
+
+/*
+ * Find out system type.
+ */
+static int
+get_system_type()
+{
+ arc_config_t *cf;
+ arc_sid_t *sid;
+ int i;
+
+ if((bios_base->magic != ARC_PARAM_BLK_MAGIC) &&
+ (bios_base->magic != ARC_PARAM_BLK_MAGIC_BUG)) {
+ return(-1); /* This is not an ARC system */
+ }
+
+ sid = (arc_sid_t *)Bios_GetSystemId();
+ cf = (arc_config_t *)Bios_GetChild(NULL);
+ if(cf) {
+ for(i = 0; i < KNOWNSYSTEMS; i++) {
+ if(strcmp(sys_types[i].sys_name, cf->id) != 0)
+ continue;
+ if(sys_types[i].sys_vend &&
+ strncmp(sys_types[i].sys_vend, sid->vendor, 8) != 0)
+ continue;
+ return(sys_types[i].sys_type); /* Found it. */
+ }
+ }
+
+ bios_putstring("UNIDENTIFIED ARC SYSTEM `");
+ if(cf)
+ bios_putstring(cf->id);
+ else
+ bios_putstring("????????");
+ bios_putstring("' VENDOR `");
+ sid->vendor[8] = 0;
+ bios_putstring(sid->vendor);
+ bios_putstring("'. Please contact OpenBSD (www.openbsd.org).\n");
+ while(1);
+}
+
+/*
+ * Incomplete version of bios_ident
+ */
+void
+bios_ident()
+{
+ system_type = get_system_type();
+ if(system_type < 0) {
+ return;
+ }
+ bios_configure_memory();
+#ifdef arc
+ displayinfo = *(arc_dsp_stat_t *)Bios_GetDisplayStatus(1);
+#endif
+}
+
+/*
+ * Return geometry of the display. Used by pccons.c to set up the
+ * display configuration.
+ */
+void
+bios_display_info(xpos, ypos, xsize, ysize)
+ int *xpos;
+ int *ypos;
+ int *xsize;
+ int *ysize;
+{
+#ifdef arc
+ *xpos = displayinfo.CursorXPosition;
+ *ypos = displayinfo.CursorYPosition;
+ *xsize = displayinfo.CursorMaxXPosition;
+ *ysize = displayinfo.CursorMaxYPosition;
+#endif
+}
+
diff --git a/sys/arch/mips/mips/clock.c b/sys/arch/mips/mips/clock.c
new file mode 100644
index 00000000000..59554ee908b
--- /dev/null
+++ b/sys/arch/mips/mips/clock.c
@@ -0,0 +1,360 @@
+/* $OpenBSD: clock.c,v 1.1 1998/01/28 12:12:06 pefo Exp $ */
+/*
+ * Copyright (c) 1997 Per Fogelstrom.
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Ralph Campbell.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * from: Utah Hdr: clock.c 1.18 91/01/21
+ *
+ * from: @(#)clock.c 8.1 (Berkeley) 6/10/93
+ * $Id: clock.c,v 1.1 1998/01/28 12:12:06 pefo Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <arc/arc/clockvar.h>
+#include <mips/archtype.h>
+
+#ifdef arc
+#include <dev/isa/isavar.h>
+#include <arc/isa/isa_machdep.h>
+#endif
+
+int clock_started = 0;
+
+/* Definition of the driver for autoconfig. */
+static int clockmatch __P((struct device *, void *, void *));
+static void clockattach __P((struct device *, struct device *, void *));
+
+void delay __P((int));
+
+struct cfdriver clock_cd = {
+ NULL, "clock", DV_DULL, NULL, 0
+};
+
+#ifdef arc
+struct cfattach clock_isa_ca = {
+ sizeof(struct clock_softc), clockmatch, clockattach
+};
+
+struct cfattach clock_pica_ca = {
+ sizeof(struct clock_softc), clockmatch, clockattach
+};
+
+struct cfattach clock_algor_ca = {
+ sizeof(struct clock_softc), clockmatch, clockattach
+};
+#endif
+
+#ifdef sgi
+struct cfattach clock_indy_ca = {
+ sizeof(struct clock_softc), clockmatch, clockattach
+};
+#endif
+
+void md_clk_attach __P((struct device *, struct device *, void *));
+int clockintr __P((void *));
+
+#define SECMIN ((unsigned)60) /* seconds per minute */
+#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
+#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */
+#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */
+
+#define LEAPYEAR(year) (((year) % 4) == 0)
+
+static int
+clockmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct cfdata *cf;
+ struct confargs *ca;
+
+ cf = cfdata;
+ ca = aux;
+ /* See how many clocks this system has */
+ switch (system_type) {
+
+#ifdef arc
+ case ACER_PICA_61:
+ /* make sure that we're looking for this type of device. */
+ if (!BUS_MATCHNAME(ca, "dallas_rtc"))
+ return (0);
+
+ break;
+
+ case DESKSTATION_RPC44:
+ case DESKSTATION_TYNE:
+ case ALGOR_P4032:
+ break;
+
+#endif
+
+#ifdef sgi
+ case SGI_INDY:
+ break;
+#endif
+ default:
+ panic("clockmatch unknown CPU");
+ }
+
+ if (cf->cf_unit >= 1)
+ return (0);
+
+ return (1);
+}
+
+static void
+clockattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct isa_attach_args *ia;
+
+ ia = aux;
+ md_clk_attach(parent, self, aux);
+
+ switch (system_type) {
+
+#ifdef arc
+ case ACER_PICA_61:
+ case ALGOR_P4032:
+ BUS_INTR_ESTABLISH((struct confargs *)aux,
+ (intr_handler_t)hardclock, self);
+ break;
+
+ case DESKSTATION_RPC44:
+ case DESKSTATION_TYNE:
+ (void)isa_intr_establish(ia->ia_ic,
+ 0, 1, 3, clockintr, 0, "clock");
+ break;
+#endif
+
+#ifdef sgi
+ case SGI_INDY:
+ BUS_INTR_ESTABLISH((struct confargs *)aux,
+ (intr_handler_t)hardclock, self);
+ break;
+#endif
+
+ default:
+ panic("clockattach: it didn't get here. really.");
+ }
+
+ printf("\n");
+}
+
+/*
+ * Wait "n" microseconds. This doesn't belong here. XXX.
+ */
+void
+delay(n)
+ int n;
+{
+ DELAY(n);
+}
+
+/*
+ * Mips machine independent clock routines.
+ */
+
+/*
+ * Start the real-time and statistics clocks. Leave stathz 0 since there
+ * are no other timers available.
+ */
+void
+cpu_initclocks()
+{
+ extern int tickadj;
+ struct clock_softc *csc = (struct clock_softc *)clock_cd.cd_devs[0];
+
+
+ /* Assume 100 Hz */
+ hz = 100;
+
+ /* Start the clock. */
+ (*csc->sc_init)(csc);
+
+ /* Recalculate theese if clock init changed hz */
+ tick = 1000000 / hz; /* number of micro-seconds between interrupts */
+ tickadj = 240000 / (60 * hz); /* can adjust 240ms in 60s */
+
+ clock_started++;
+}
+
+/*
+ * We assume newhz is either stathz or profhz, and that neither will
+ * change after being set up above. Could recalculate intervals here
+ * but that would be a drag.
+ */
+void
+setstatclockrate(newhz)
+ int newhz;
+{
+}
+
+/*
+ * This code is defunct after 2099.
+ * Will Unix still be here then??
+ */
+static short dayyr[12] = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+/*
+ * Initialize the time of day register, based on the time base which
+ * is, e.g. from a filesystem. Base provides the time to within six
+ * months, and the time of year clock (if any) provides the rest.
+ */
+void
+inittodr(base)
+ time_t base;
+{
+ struct tod_time c;
+ struct clock_softc *csc = (struct clock_softc *)clock_cd.cd_devs[0];
+ register int days, yr;
+ long deltat;
+ int badbase;
+
+ if (base < 5*SECYR) {
+ printf("WARNING: preposterous time in file system");
+ /* read the system clock anyway */
+ base = 6*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ } else
+ badbase = 0;
+
+ /* Read RTC chip registers */
+ (*csc->sc_get)(csc, base, &c);
+
+ csc->sc_initted = 1;
+
+ /* simple sanity checks */
+ if (c.year < 70 || c.mon < 1 || c.mon > 12 || c.day < 1 ||
+ c.day > 31 || c.hour > 23 || c.min > 59 || c.sec > 59) {
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the TODR.
+ */
+ time.tv_sec = base;
+ if (!badbase) {
+ printf("WARNING: preposterous clock chip time\n");
+ resettodr();
+ }
+ goto bad;
+ }
+ days = 0;
+ for (yr = 70; yr < c.year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[c.mon - 1] + c.day - 1;
+ if (LEAPYEAR(yr) && c.mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ time.tv_sec = days * SECDAY + c.hour * 3600 + c.min * 60 + c.sec;
+
+ if (!badbase) {
+ /*
+ * See if we gained/lost two or more days;
+ * if so, assume something is amiss.
+ */
+ deltat = time.tv_sec - base;
+ if (deltat < 0)
+ deltat = -deltat;
+ if (deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+ }
+bad:
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the TODR based on the time value; used when the TODR has a
+ * preposterous value and also when the time is reset by the stime
+ * system call.
+ * Also called when the TODR goes past TODRZERO + 100*(SECYEAR+2*SECDAY)
+ * (e.g. on Jan 2 just after midnight) to wrap the TODR around.
+ */
+void
+resettodr()
+{
+ struct tod_time c;
+ struct clock_softc *csc = (struct clock_softc *)clock_cd.cd_devs[0];
+ register int t, t2;
+
+ if(!csc->sc_initted)
+ return;
+
+ /* compute the day of week. 1 is Sunday*/
+ t2 = time.tv_sec / SECDAY;
+ c.dow = (t2 + 5) % 7; /* 1/1/1970 was thursday */
+
+ /* compute the year */
+ t2 = time.tv_sec / SECDAY;
+ c.year = 69;
+ while (t2 >= 0) { /* whittle off years */
+ t = t2;
+ c.year++;
+ t2 -= LEAPYEAR(c.year) ? 366 : 365;
+ }
+
+ /* t = month + day; separate */
+ t2 = LEAPYEAR(c.year);
+ for (c.mon = 1; c.mon < 12; c.mon++)
+ if (t < dayyr[c.mon] + (t2 && c.mon > 1))
+ break;
+
+ c.day = t - dayyr[c.mon - 1] + 1;
+ if (t2 && c.mon > 2)
+ c.day--;
+
+ /* the rest is easy */
+ t = time.tv_sec % SECDAY;
+ c.hour = t / 3600;
+ t %= 3600;
+ c.min = t / 60;
+ c.sec = t % 60;
+
+ (*csc->sc_set)(csc, &c);
+}
diff --git a/sys/arch/mips/mips/cpu.c b/sys/arch/mips/mips/cpu.c
new file mode 100644
index 00000000000..60453e6dcd0
--- /dev/null
+++ b/sys/arch/mips/mips/cpu.c
@@ -0,0 +1,207 @@
+/* $OpenBSD: cpu.c,v 1.1 1998/01/28 12:12:07 pefo Exp $ */
+
+/*
+ * Copyright (c) 1997 Per Fogelstrom
+ *
+ * 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 under OpenBSD by
+ * Per Fogelstrom.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/device.h>
+
+#include <machine/pte.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+
+
+/* Definition of the driver for autoconfig. */
+static int cpumatch(struct device *, void *, void *);
+static void cpuattach(struct device *, struct device *, void *);
+
+struct cfattach cpu_ca = {
+ sizeof(struct device), cpumatch, cpuattach
+};
+struct cfdriver cpu_cd = {
+ NULL, "cpu", DV_DULL, NULL, 0
+};
+
+static int
+cpumatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+
+ /* make sure that we're looking for a CPU. */
+ if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
+ return (0);
+
+ return (1);
+}
+
+static void
+cpuattach(parent, dev, aux)
+ struct device *parent;
+ struct device *dev;
+ void *aux;
+{
+
+ printf(": ");
+
+ switch(cpu_id.cpu.cp_imp) {
+
+ case MIPS_R2000:
+ printf("MIPS R2000 CPU");
+ break;
+ case MIPS_R3000:
+ printf("MIPS R3000 CPU");
+ break;
+ case MIPS_R6000:
+ printf("MIPS R6000 CPU");
+ break;
+ case MIPS_R4000:
+ if(CpuPrimaryInstCacheSize == 16384)
+ printf("MIPS R4400 CPU");
+ else
+ printf("MIPS R4000 CPU");
+ break;
+ case MIPS_R3LSI:
+ printf("LSI Logic R3000 derivate");
+ break;
+ case MIPS_R6000A:
+ printf("MIPS R6000A CPU");
+ break;
+ case MIPS_R3IDT:
+ printf("IDT R3000 derivate");
+ break;
+ case MIPS_R10000:
+ printf("MIPS R10000 CPU");
+ break;
+ case MIPS_R4200:
+ printf("NEC VR4200 CPU (ICE)");
+ break;
+ case MIPS_R4300:
+ printf("NEC VR4300 CPU");
+ break;
+ case MIPS_R8000:
+ printf("MIPS R8000 Blackbird/TFP CPU");
+ break;
+ case MIPS_R4600:
+ printf("QED R4600 Orion CPU");
+ break;
+ case MIPS_R4700:
+ printf("QED R4700 Orion CPU");
+ break;
+ case MIPS_R3TOSH:
+ printf("Toshiba R3000 based CPU");
+ break;
+ case MIPS_RM5230:
+ printf("QED RM5230 based CPU");
+ break;
+ case MIPS_UNKC2:
+ default:
+ printf("Unknown CPU type (0x%x)",cpu_id.cpu.cp_imp);
+ break;
+ }
+ printf(" Rev. %d.%d with ", cpu_id.cpu.cp_majrev, cpu_id.cpu.cp_minrev);
+
+
+ switch(fpu_id.cpu.cp_imp) {
+
+ case MIPS_SOFT:
+ printf("Software emulation float");
+ break;
+ case MIPS_R2360:
+ printf("MIPS R2360 FPC");
+ break;
+ case MIPS_R2010:
+ printf("MIPS R2010 FPC");
+ break;
+ case MIPS_R3010:
+ printf("MIPS R3010 FPC");
+ break;
+ case MIPS_R6010:
+ printf("MIPS R6010 FPC");
+ break;
+ case MIPS_R4010:
+ printf("MIPS R4010 FPC");
+ break;
+ case MIPS_R31LSI:
+ printf("FPC");
+ break;
+ case MIPS_R10010:
+ printf("MIPS R10000 FPU");
+ break;
+ case MIPS_R4210:
+ printf("NEC VR4200 FPC (ICE)");
+ break;
+ case MIPS_R8000:
+ printf("MIPS R8000 Blackbird/TFP");
+ break;
+ case MIPS_R4600:
+ printf("QED R4600 Orion FPC");
+ break;
+ case MIPS_R4700:
+ printf("QED R4700 Orion FPC");
+ break;
+ case MIPS_R3TOSH:
+ printf("Toshiba R3000 based FPC");
+ break;
+ case MIPS_R5000:
+ printf("MIPS R5000 based FPC");
+ break;
+ case MIPS_RM5230:
+ printf("QED RM5230 based FPC");
+ break;
+ case MIPS_UNKF1:
+ default:
+ printf("Unknown FPU type (0x%x)", fpu_id.cpu.cp_imp);
+ break;
+ }
+ printf(" Rev. %d.%d", fpu_id.cpu.cp_majrev, fpu_id.cpu.cp_minrev);
+ printf("\n");
+
+ printf("Primary cache size: %dkb Instruction, %dkb Data.",
+ CpuPrimaryInstCacheSize / 1024,
+ CpuPrimaryDataCacheSize / 1024);
+ if(CpuTwoWayCache)
+ printf(" Two way set associative.\n");
+ else
+ printf(" Direct mapped.\n");
+
+ if(l2cache_is_snooping)
+ printf("Missing L2 cache or Snooping L2 cache.\n");
+ else
+ printf("No Snooping L2 cache!\n");
+}
+
diff --git a/sys/arch/mips/mips/cpu_ecoff.c b/sys/arch/mips/mips/cpu_ecoff.c
new file mode 100644
index 00000000000..9e10d578e04
--- /dev/null
+++ b/sys/arch/mips/mips/cpu_ecoff.c
@@ -0,0 +1,92 @@
+/* $OpenBSD: cpu_ecoff.c,v 1.1 1998/01/28 12:12:07 pefo Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by Ralph
+ * Campbell.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)machdep.c 8.3 (Berkeley) 1/12/94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+#include <sys/exec.h>
+#include <sys/resourcevar.h>
+#include <vm/vm.h>
+
+#include <machine/reg.h>
+
+#if defined(_KERN_DO_ECOFF)
+#include <sys/exec_ecoff.h>
+
+void cpu_exec_ecoff_setregs __P((struct proc *, struct exec_package *,
+ u_long, register_t *));
+void
+cpu_exec_ecoff_setregs(p, pack, stack, retval)
+ struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+ register_t *retval;
+{
+ struct ecoff_aouthdr *eap;
+
+ setregs(p, pack, stack, retval);
+ eap = (struct ecoff_aouthdr *)
+ ((caddr_t)pack->ep_hdr + sizeof(struct ecoff_filehdr));
+ p->p_md.md_regs[GP] = eap->ea_gp_value;
+}
+
+/*
+ * cpu_exec_ecoff_hook():
+ * cpu-dependent ECOFF format hook for execve().
+ *
+ * Do any machine-dependent diddling of the exec package when doing ECOFF.
+ *
+ */
+int
+cpu_exec_ecoff_hook(p, epp)
+ struct proc *p;
+ struct exec_package *epp;
+{
+#ifdef COMPAT_ULTRIX
+ extern struct emul emul_ultrix;
+
+ epp->ep_emul = &emul_ultrix;
+#endif
+ return 0;
+}
+
+#endif /* _KERN_DO_ECOFF */
diff --git a/sys/arch/mips/mips/disksubr.c b/sys/arch/mips/mips/disksubr.c
new file mode 100644
index 00000000000..0ad138cd7ab
--- /dev/null
+++ b/sys/arch/mips/mips/disksubr.c
@@ -0,0 +1,523 @@
+/* $OpenBSD: disksubr.c,v 1.1 1998/01/28 12:12:07 pefo Exp $ */
+/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/syslog.h>
+#include <sys/disk.h>
+
+#define b_cylin b_resid
+
+#define BOOT_MAGIC 0xAA55
+#define BOOT_MAGIC_OFF (DOSPARTOFF+NDOSPART*sizeof(struct dos_partition))
+
+void
+dk_establish(dk, dev)
+ struct disk *dk;
+ struct device *dev;
+{
+}
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated stategy routine.
+ * The label must be partly set up before this:
+ * secpercyl, secsize and anything required for a block i/o read
+ * operation in the driver's strategy/start routines
+ * must be filled in before calling us.
+ *
+ * If dos partition table requested, attempt to load it and
+ * find disklabel inside a DOS partition. Also, if bad block
+ * table needed, attempt to extract it as well. Return buffer
+ * for use in signalling errors if requested.
+ *
+ * We would like to check if each MBR has a valid BOOT_MAGIC, but
+ * we cannot because it doesn't always exist. So.. we assume the
+ * MBR is valid.
+ *
+ * Returns null on success and an error string on failure.
+ */
+char *
+readdisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ void (*strat) __P((struct buf *));
+ register struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ struct dos_partition *dp = osdep->dosparts, *dp2;
+ struct dkbad *bdp = &DKBAD(osdep);
+ struct buf *bp;
+ struct disklabel *dlp;
+ char *msg = NULL, *cp;
+ int dospartoff, cyl, i, ourpart = -1;
+
+ /* minimal requirements for archtypal disk label */
+ if (lp->d_secsize == 0)
+ lp->d_secsize = DEV_BSIZE;
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = 0x1fffffff;
+ lp->d_npartitions = RAW_PART + 1;
+ for (i = 0; i < RAW_PART; i++) {
+ lp->d_partitions[i].p_size = 0;
+ lp->d_partitions[i].p_offset = 0;
+ }
+ if (lp->d_partitions[i].p_size == 0)
+ lp->d_partitions[i].p_size = 0x1fffffff;
+ lp->d_partitions[i].p_offset = 0;
+
+ /* get a buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ /* do dos partitions in the process of getting disklabel? */
+ dospartoff = 0;
+ cyl = LABELSECTOR / lp->d_secpercyl;
+ if (dp) {
+ daddr_t part_blkno = DOSBBSECTOR;
+ unsigned long extoff = 0;
+ int wander = 1, n = 0, loop = 0;
+
+ /*
+ * Read dos partition table, follow extended partitions.
+ * Map the partitions to disklabel entries i-p
+ */
+ while (wander && n < 8 && loop < 8) {
+ loop++;
+ wander = 0;
+
+ /* read boot record */
+ bp->b_blkno = part_blkno;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = part_blkno / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through dos partition table */
+ if (biowait(bp)) {
+ msg = "dos partition I/O error";
+ goto done;
+ }
+ bcopy(bp->b_data + DOSPARTOFF, dp, NDOSPART * sizeof(*dp));
+
+ if (ourpart == -1) {
+ /* Search for our MBR partition */
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (get_le(&dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_OPENBSD)
+ ourpart = i;
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (get_le(&dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_386BSD)
+ ourpart = i;
+ if (ourpart == -1)
+ goto donot;
+ /*
+ * This is our MBR partition. need sector address
+ * for SCSI/IDE, cylinder for ESDI/ST506/RLL
+ */
+ dp2 = &dp[ourpart];
+ dospartoff = get_le(&dp2->dp_start) + part_blkno;
+ cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
+
+ /* XXX build a temporary disklabel */
+ lp->d_partitions[0].p_size = get_le(&dp2->dp_size);
+ lp->d_partitions[0].p_offset =
+ get_le(&dp2->dp_start) + part_blkno;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = dp2->dp_ehd + 1;
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = DPSECT(dp2->dp_esect);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_ntracks *
+ lp->d_nsectors;
+ }
+donot:
+ /*
+ * In case the disklabel read below fails, we want to
+ * provide a fake label in i-p.
+ */
+ for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ if (dp2->dp_typ == DOSPTYP_OPENBSD)
+ continue;
+ if (get_le(&dp2->dp_size) > lp->d_secperunit)
+ continue;
+ if (get_le(&dp2->dp_size))
+ pp->p_size = get_le(&dp2->dp_size);
+ if (get_le(&dp2->dp_start))
+ pp->p_offset =
+ get_le(&dp2->dp_start) + part_blkno;
+
+ switch (dp2->dp_typ) {
+ case DOSPTYP_UNUSED:
+ for (cp = (char *)dp2;
+ cp < (char *)(dp2 + 1); cp++)
+ if (*cp)
+ break;
+ /*
+ * Was it all zeroes? If so, it is
+ * an unused entry that we don't
+ * want to show.
+ */
+ if (cp == (char *)(dp2 + 1))
+ continue;
+ lp->d_partitions[8 + n++].p_fstype =
+ FS_UNUSED;
+ break;
+
+ case DOSPTYP_LINUX:
+ pp->p_fstype = FS_EXT2FS;
+ n++;
+ break;
+
+ case DOSPTYP_FAT12:
+ case DOSPTYP_FAT16S:
+ case DOSPTYP_FAT16B:
+ case DOSPTYP_FAT16C:
+ case DOSPTYP_FAT32:
+ pp->p_fstype = FS_MSDOS;
+ n++;
+ break;
+ case DOSPTYP_EXTEND:
+ part_blkno = get_le(&dp2->dp_start) + extoff;
+ if (!extoff)
+ extoff = get_le(&dp2->dp_start);
+ wander = 1;
+ break;
+ default:
+ pp->p_fstype = FS_OTHER;
+ n++;
+ break;
+ }
+ }
+ }
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 64*1024; /* XXX ? */
+ lp->d_npartitions = MAXPARTITIONS;
+ }
+
+ /* next, dig out disk label */
+ bp->b_blkno = dospartoff + LABELSECTOR;
+ bp->b_cylin = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if (biowait(bp)) {
+ /* XXX we return the faked label built so far */
+ msg = "disk label I/O error";
+ goto done;
+ }
+ for (dlp = (struct disklabel *)bp->b_data;
+ dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
+ dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+ if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
+ if (msg == NULL)
+ msg = "no disk label";
+ } else if (dlp->d_npartitions > MAXPARTITIONS ||
+ dkcksum(dlp) != 0)
+ msg = "disk label corrupted";
+ else {
+ *lp = *dlp;
+ msg = NULL;
+ break;
+ }
+ }
+
+ if (msg) {
+#if defined(CD9660)
+ if (iso_disklabelspoof(dev, strat, lp) == 0)
+ msg = NULL;
+#endif
+ goto done;
+ }
+
+ /* obtain bad sector table if requested and present */
+ if (bdp && (lp->d_flags & D_BADSECT)) {
+ struct dkbad *db;
+
+ i = 0;
+ do {
+ /* read a bad sector table */
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i;
+ if (lp->d_secsize > DEV_BSIZE)
+ bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+ else
+ bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_cylin = lp->d_ncylinders - 1;
+ (*strat)(bp);
+
+ /* if successful, validate, otherwise try another */
+ if (biowait(bp)) {
+ msg = "bad sector table I/O error";
+ } else {
+ db = (struct dkbad *)(bp->b_data);
+#define DKBAD_MAGIC 0x4321
+ if (db->bt_mbz == 0
+ && db->bt_flag == DKBAD_MAGIC) {
+ msg = NULL;
+ *bdp = *db;
+ break;
+ } else
+ msg = "bad sector table corrupted";
+ }
+ } while ((bp->b_flags & B_ERROR) && (i += 2) < 10 &&
+ i < lp->d_nsectors);
+ }
+
+done:
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ return (msg);
+}
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+int
+setdisklabel(olp, nlp, openmask, osdep)
+ register struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *osdep;
+{
+ register i;
+ register struct partition *opp, *npp;
+
+ /* sanity clause */
+ if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 ||
+ (nlp->d_secsize % DEV_BSIZE) != 0)
+ return(EINVAL);
+
+ /* special case to allow disklabel to be invalidated */
+ if (nlp->d_magic == 0xffffffff) {
+ *olp = *nlp;
+ return (0);
+ }
+
+ if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
+ dkcksum(nlp) != 0)
+ return (EINVAL);
+
+ /* XXX missing check if other dos partitions will be overwritten */
+
+ while (openmask != 0) {
+ i = ffs(openmask) - 1;
+ openmask &= ~(1 << i);
+ if (nlp->d_npartitions <= i)
+ return (EBUSY);
+ opp = &olp->d_partitions[i];
+ npp = &nlp->d_partitions[i];
+ if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
+ return (EBUSY);
+ /*
+ * Copy internally-set partition information
+ * if new label doesn't include it. XXX
+ */
+ if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
+ npp->p_fstype = opp->p_fstype;
+ npp->p_fsize = opp->p_fsize;
+ npp->p_frag = opp->p_frag;
+ npp->p_cpg = opp->p_cpg;
+ }
+ }
+ nlp->d_checksum = 0;
+ nlp->d_checksum = dkcksum(nlp);
+ *olp = *nlp;
+ return (0);
+}
+
+
+/*
+ * Write disk label back to device after modification.
+ * XXX cannot handle OpenBSD partitions in extended partitions!
+ */
+int
+writedisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ void (*strat) __P((struct buf *));
+ register struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ struct dos_partition *dp = osdep->dosparts, *dp2;
+ struct buf *bp;
+ struct disklabel *dlp;
+ int error, dospartoff, cyl, i;
+ int ourpart = -1;
+
+ /* get a buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ /* do dos partitions in the process of getting disklabel? */
+ dospartoff = 0;
+ cyl = LABELSECTOR / lp->d_secpercyl;
+ if (dp) {
+ /* read master boot record */
+ bp->b_blkno = DOSBBSECTOR;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl;
+ (*strat)(bp);
+
+ if ((error = biowait(bp)) != 0)
+ goto done;
+
+ /* XXX how do we check veracity/bounds of this? */
+ bcopy(bp->b_data + DOSPARTOFF, dp,
+ NDOSPART * sizeof(*dp));
+
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
+ if (get_le(&dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD)
+ ourpart = i;
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++)
+ if (get_le(&dp2->dp_size) && dp2->dp_typ == DOSPTYP_386BSD)
+ ourpart = i;
+
+ if (ourpart != -1) {
+ dp2 = &dp[ourpart];
+
+ /*
+ * need sector address for SCSI/IDE,
+ * cylinder for ESDI/ST506/RLL
+ */
+ dospartoff = get_le(&dp2->dp_start);
+ cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
+ }
+ }
+
+ /* next, dig out disk label */
+ bp->b_blkno = dospartoff + LABELSECTOR;
+ bp->b_cylin = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if ((error = biowait(bp)) != 0)
+ goto done;
+ for (dlp = (struct disklabel *)bp->b_data;
+ dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp));
+ dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+ if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
+ dkcksum(dlp) == 0) {
+ *dlp = *lp;
+ bp->b_flags = B_BUSY | B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+ goto done;
+ }
+ }
+
+ /* Write it in the regular place. */
+ *(struct disklabel *)bp->b_data = *lp;
+ bp->b_flags = B_BUSY | B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+ goto done;
+
+done:
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ return (error);
+}
+
+/*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition. Adjust transfer
+ * if needed, and signal errors or early completion.
+ */
+int
+bounds_check_with_label(bp, lp, osdep, wlabel)
+ struct buf *bp;
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int wlabel;
+{
+#define blockpersec(count, lp) ((count) * (((lp)->d_secsize) / DEV_BSIZE))
+ struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
+ int labelsector = blockpersec(lp->d_partitions[RAW_PART].p_offset, lp) +
+ LABELSECTOR;
+ int sz = howmany(bp->b_bcount, DEV_BSIZE);
+
+ if (bp->b_blkno + sz > blockpersec(p->p_size, lp)) {
+ sz = blockpersec(p->p_size, lp) - bp->b_blkno;
+ if (sz == 0) {
+ /* If exactly at end of disk, return EOF. */
+ bp->b_resid = bp->b_bcount;
+ goto done;
+ }
+ if (sz < 0) {
+ /* If past end of disk, return EINVAL. */
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+ /* Otherwise, truncate request. */
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+
+ /* Overwriting disk label? */
+ if (bp->b_blkno + blockpersec(p->p_offset, lp) <= labelsector &&
+#if LABELSECTOR != 0
+ bp->b_blkno + blockpersec(p->p_offset, lp) + sz > labelsector &&
+#endif
+ (bp->b_flags & B_READ) == 0 && !wlabel) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+
+ /* calculate cylinder for disksort to order transfers with */
+ bp->b_cylin = (bp->b_blkno + blockpersec(p->p_offset, lp)) /
+ lp->d_secpercyl;
+ return (1);
+
+bad:
+ bp->b_flags |= B_ERROR;
+done:
+ return (0);
+}
diff --git a/sys/arch/mips/mips/mainbus.c b/sys/arch/mips/mips/mainbus.c
new file mode 100644
index 00000000000..d809493f8b2
--- /dev/null
+++ b/sys/arch/mips/mips/mainbus.c
@@ -0,0 +1,191 @@
+/* $OpenBSD: mainbus.c,v 1.1 1998/01/28 12:12:08 pefo Exp $ */
+
+/*
+ * Copyright (c) 1997 Per Fogelstrom.
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+
+#include <mips/archtype.h>
+#include <machine/autoconf.h>
+
+struct mainbus_softc {
+ struct device sc_dv;
+ struct abus sc_bus;
+};
+
+/* Definition of the mainbus driver. */
+static int mbmatch __P((struct device *, void *, void *));
+static void mbattach __P((struct device *, struct device *, void *));
+static int mbprint __P((void *, const char *));
+
+struct cfattach mainbus_ca = {
+ sizeof(struct device), mbmatch, mbattach
+};
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL, NULL, 0
+};
+
+void mb_intr_establish __P((struct confargs *, int (*)(void *), void *));
+void mb_intr_disestablish __P((struct confargs *));
+caddr_t mb_cvtaddr __P((struct confargs *));
+int mb_matchname __P((struct confargs *, char *));
+
+static int
+mbmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct cfdata *cf = cfdata;
+
+ if (cf->cf_unit > 0)
+ return(0);
+ return(1);
+}
+
+static void
+mbattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ struct confargs nca;
+
+ printf("\n");
+
+ sc->sc_bus.ab_dv = (struct device *)sc;
+ sc->sc_bus.ab_type = BUS_MAIN;
+ sc->sc_bus.ab_intr_establish = mb_intr_establish;
+ sc->sc_bus.ab_intr_disestablish = mb_intr_disestablish;
+ sc->sc_bus.ab_cvtaddr = mb_cvtaddr;
+ sc->sc_bus.ab_matchname = mb_matchname;
+
+ /*
+ * Try to find and attach all of the CPUs in the machine.
+ * ( Right now only one CPU so code is simple )
+ */
+
+ nca.ca_name = "cpu";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+
+#ifdef arc
+ if (system_type == ACER_PICA_61) {
+ nca.ca_name = "pica";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+ }
+ if (system_type == ALGOR_P4032) {
+ nca.ca_name = "algor";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+ }
+
+ /* The following machines have a PCI bus */
+ if (system_type == ALGOR_P4032) {
+ nca.ca_name = "pbcpcibr";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+ }
+
+ /* The following machines have an ISA bus */
+ if (system_type == ACER_PICA_61 ||
+ system_type == DESKSTATION_TYNE ||
+ system_type == DESKSTATION_RPC44) {
+ nca.ca_name = "isabr";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+ }
+#endif
+
+#ifdef sgi
+ if (system_type == SGI_INDY) {
+ nca.ca_name = "indy";
+ nca.ca_slot = 0;
+ nca.ca_offset = 0;
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+ }
+#endif
+}
+
+static int
+mbprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ if (pnp)
+ return (QUIET);
+ return (UNCONF);
+}
+
+void
+mb_intr_establish(ca, handler, val)
+ struct confargs *ca;
+ int (*handler) __P((void *));
+ void *val;
+{
+
+ panic("can never mb_intr_establish");
+}
+
+void
+mb_intr_disestablish(ca)
+ struct confargs *ca;
+{
+ panic("can never mb_intr_disestablish");
+}
+
+caddr_t
+mb_cvtaddr(ca)
+ struct confargs *ca;
+{
+ return (NULL);
+}
+
+int
+mb_matchname(ca, name)
+ struct confargs *ca;
+ char *name;
+{
+ return (strcmp(name, ca->ca_name) == 0);
+}
diff --git a/sys/arch/mips/mips/mem.c b/sys/arch/mips/mips/mem.c
new file mode 100644
index 00000000000..68b8fa1d6a7
--- /dev/null
+++ b/sys/arch/mips/mips/mem.c
@@ -0,0 +1,180 @@
+/* $OpenBSD: mem.c,v 1.1 1998/01/28 12:12:08 pefo Exp $ */
+/* $NetBSD: mem.c,v 1.6 1995/04/10 11:55:03 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Ralph Campbell.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/msgbuf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <machine/pte.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+
+extern vm_offset_t avail_end;
+caddr_t zeropage;
+
+int mmopen __P((dev_t, int, int));
+int mmclose __P((dev_t, int, int));
+int mmrw __P((dev_t, struct uio *uio, int));
+int mmmmap __P((dev_t, int, int));
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ register vm_offset_t v;
+ register int c;
+ register struct iovec *iov;
+ int error = 0;
+
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+/* minor device 0 is physical memory */
+ case 0:
+ v = uio->uio_offset;
+ c = iov->iov_len;
+ if (v + c > ctob(physmem))
+ return (EFAULT);
+ v += CACHED_MEMORY_ADDR;
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ if (v < CACHED_MEMORY_ADDR)
+ return (EFAULT);
+ if (v + c > PHYS_TO_CACHED(avail_end +
+ sizeof (struct msgbuf)) &&
+ (v < KSEG2_ADDR ||
+ !kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE)))
+ return (EFAULT);
+
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 2 is EOF/RATHOLE */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
+ case 12:
+ if (uio->uio_rw == UIO_WRITE) {
+ c = iov->iov_len;
+ break;
+ }
+ if (zeropage == NULL) {
+ zeropage = (caddr_t)
+ malloc(CLBYTES, M_TEMP, M_WAITOK);
+ bzero(zeropage, CLBYTES);
+ }
+ c = min(iov->iov_len, CLBYTES);
+ error = uiomove(zeropage, c, uio);
+ continue;
+
+ default:
+ return (ENXIO);
+ }
+ if (error)
+ break;
+ iov->iov_base += c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ return (error);
+}
+
+/*ARGSUSED*/
+int
+mmmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+
+ return (EOPNOTSUPP);
+}
diff --git a/sys/arch/mips/mips/minidebug.c b/sys/arch/mips/mips/minidebug.c
new file mode 100644
index 00000000000..598dd26f5ac
--- /dev/null
+++ b/sys/arch/mips/mips/minidebug.c
@@ -0,0 +1,953 @@
+/* $OpenBSD: minidebug.c,v 1.1 1998/01/28 12:12:09 pefo Exp $ */
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93
+ * $Id: minidebug.c,v 1.1 1998/01/28 12:12:09 pefo Exp $
+ */
+
+/*
+ * Define machine dependent primitives for mdb.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <dev/cons.h>
+#include <machine/pte.h>
+#include <vm/vm_prot.h>
+#undef SP
+#include <machine/cpu.h>
+#include <machine/reg.h>
+#include <machine/intr.h>
+#include <machine/trap.h>
+#include <machine/mips_opcode.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+
+static char *op_name[64] = {
+/* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz",
+/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
+/*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
+/*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
+/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
+/*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
+/*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld",
+/*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd"
+};
+
+static char *spec_name[64] = {
+/* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
+/* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync",
+/*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
+/*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu",
+/*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
+/*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
+/*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
+/*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
+};
+
+static char *bcond_name[32] = {
+/* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
+/* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
+/*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
+/*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
+};
+
+static char *cop1_name[64] = {
+/* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
+/* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
+/*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
+/*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
+/*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
+/*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
+/*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
+ "fcmp.ole","fcmp.ule",
+/*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
+ "fcmp.le","fcmp.ngt"
+};
+
+static char *fmt_name[16] = {
+ "s", "d", "e", "fmt3",
+ "w", "fmt5", "fmt6", "fmt7",
+ "fmt8", "fmt9", "fmta", "fmtb",
+ "fmtc", "fmtd", "fmte", "fmtf"
+};
+
+static char *reg_name[32] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+};
+
+static char *c0_opname[64] = {
+ "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
+ "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
+ "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
+ "eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
+ "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
+ "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
+ "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
+ "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
+};
+
+static char *c0_reg[32] = {
+ "index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
+ "badvaddr","count","tlbhi","c0r11","sr","cause","epc", "prid",
+ "config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
+ "c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
+};
+
+extern u_int mdbpeek __P((int));
+extern void mdbpoke __P((int, int));
+extern void trapDump __P((char *));
+extern void stacktrace __P((void));
+extern u_int MipsEmulateBranch __P((int *, int, int, u_int));
+extern char *trap_type[];
+extern int num_tlbentries;
+static void arc_dump_tlb __P((int,int));
+static void prt_break __P((void));
+static int mdbprintins __P((int, int));
+static void mdbsetsstep __P((void));
+static int mdbclrsstep __P((int));
+static void print_regs __P((void));
+static void break_insert __P((void));
+static void break_restore __P((void));
+static int break_find __P((int));
+
+struct pcb mdbpcb;
+int mdbmkfault;
+
+#define MAXBRK 10
+struct brk {
+ int inst;
+ int addr;
+} brk_tab[MAXBRK];
+
+/*
+ * Mini debugger for kernel.
+ */
+static int
+gethex(u_int *val, u_int dotval)
+{
+ u_int c;
+
+ *val = 0;
+ while((c = cngetc()) != '\e' && c != '\n' && c != '\r') {
+ if(c >= '0' && c <= '9') {
+ *val = (*val << 4) + c - '0';
+ cnputc(c);
+ }
+ else if(c >= 'a' && c <= 'f') {
+ *val = (*val << 4) + c - 'a' + 10;
+ cnputc(c);
+ }
+ else if(c == '\b') {
+ *val = *val >> 4;
+ printf("\b \b");
+ }
+ else if(c == ',') {
+ cnputc(c);
+ return(c);
+ }
+ else if(c == '.') {
+ *val = dotval;;
+ cnputc(c);
+ }
+ }
+ if(c == '\r')
+ c = '\n';
+ return(c);
+}
+
+static
+void dump(u_int *addr, u_int size)
+{
+ int cnt;
+
+ cnt = 0;
+
+ size = (size + 3) / 4;
+ while(size--) {
+ if((cnt++ & 3) == 0)
+ printf("\n%08x: ",(int)addr);
+ printf("%08x ",*addr++);
+ }
+}
+
+static void
+print_regs()
+{
+ printf("\n");
+ printf("T0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ mdbpcb.pcb_regs[T0],mdbpcb.pcb_regs[T1],
+ mdbpcb.pcb_regs[T2],mdbpcb.pcb_regs[T3],
+ mdbpcb.pcb_regs[T4],mdbpcb.pcb_regs[T5],
+ mdbpcb.pcb_regs[T6],mdbpcb.pcb_regs[T7]);
+ printf("T8-9 %08x %08x A0-4 %08x %08x %08x %08x\n",
+ mdbpcb.pcb_regs[T8],mdbpcb.pcb_regs[T9],
+ mdbpcb.pcb_regs[A0],mdbpcb.pcb_regs[A1],
+ mdbpcb.pcb_regs[A2],mdbpcb.pcb_regs[A3]);
+ printf("S0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ mdbpcb.pcb_regs[S0],mdbpcb.pcb_regs[S1],
+ mdbpcb.pcb_regs[S2],mdbpcb.pcb_regs[S3],
+ mdbpcb.pcb_regs[S4],mdbpcb.pcb_regs[S5],
+ mdbpcb.pcb_regs[S6],mdbpcb.pcb_regs[S7]);
+ printf(" S8 %08x V0-1 %08x %08x GP %08x SP %08x\n",
+ mdbpcb.pcb_regs[S8],mdbpcb.pcb_regs[V0],
+ mdbpcb.pcb_regs[V1],mdbpcb.pcb_regs[GP],
+ mdbpcb.pcb_regs[SP]);
+ printf(" AT %08x PC %08x RA %08x SR %08x",
+ mdbpcb.pcb_regs[AST],mdbpcb.pcb_regs[PC],
+ mdbpcb.pcb_regs[RA],mdbpcb.pcb_regs[SR]);
+}
+
+void
+set_break(int va)
+{
+ int i;
+
+ va = va & ~3;
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr == 0) {
+ brk_tab[i].addr = va;
+ brk_tab[i].inst = *(u_int *)va;
+ return;
+ }
+ }
+ printf(" Break table full!!");
+}
+
+void
+del_break(int va)
+{
+ int i;
+
+ va = va & ~3;
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr == va) {
+ brk_tab[i].addr = 0;
+ return;
+ }
+ }
+ printf(" Break to remove not found!!");
+}
+
+static void
+break_insert()
+{
+ int i;
+
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr != 0) {
+ brk_tab[i].inst = *(u_int *)brk_tab[i].addr;
+ *(u_int *)brk_tab[i].addr = BREAK_BRKPT;
+ R4K_FlushDCache(brk_tab[i].addr,4);
+ R4K_FlushICache(brk_tab[i].addr,4);
+ }
+ }
+}
+
+static void
+break_restore()
+{
+ int i;
+
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr != 0) {
+ *(u_int *)brk_tab[i].addr = brk_tab[i].inst;
+ R4K_FlushDCache(brk_tab[i].addr,4);
+ R4K_FlushICache(brk_tab[i].addr,4);
+ }
+ }
+}
+
+static int
+break_find(va)
+ int va;
+{
+ int i;
+
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr == va) {
+ return(i);
+ }
+ }
+ return(-1);
+}
+
+void
+prt_break()
+{
+ int i;
+
+ for(i = 0; i < MAXBRK; i++) {
+ if(brk_tab[i].addr != 0) {
+ printf("\n %08x\t", brk_tab[i].addr);
+ mdbprintins(brk_tab[i].inst, brk_tab[i].addr);
+ }
+ }
+}
+
+int
+mdb(int causeReg, int vadr, int p, int kernelmode)
+{
+ int c;
+ int newaddr;
+ int size;
+ int cause;
+static int ssandrun; /* Single step and run flag (when cont at brk) */
+
+ splhigh();
+ cause = (causeReg & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT;
+ newaddr = (int)(mdbpcb.pcb_regs[PC]);
+ switch(cause) {
+ case T_BREAK:
+ if(*(int *)newaddr == BREAK_SOVER) {
+ break_restore();
+ mdbpcb.pcb_regs[PC] += 4;
+ printf("\nStop break (panic)\n# ");
+ printf(" %08x\t",newaddr);
+ mdbprintins(*(int *)newaddr, newaddr);
+ printf("\n# ");
+ break;
+ }
+ if(*(int *)newaddr == BREAK_BRKPT) {
+ break_restore();
+ printf("\rBRK %08x\t",newaddr);
+ if(mdbprintins(*(int *)newaddr, newaddr)) {
+ newaddr += 4;
+ printf("\n %08x\t",newaddr);
+ mdbprintins(*(int *)newaddr, newaddr);
+ }
+ printf("\n# ");
+ break;
+ }
+ if(mdbclrsstep(causeReg)) {
+ if(ssandrun) { /* Step over bp before free run */
+ ssandrun = 0;
+ break_insert();
+ return(TRUE);
+ }
+ printf("\r %08x\t",newaddr);
+ if(mdbprintins(*(int *)newaddr, newaddr)) {
+ newaddr += 4;
+ printf("\n %08x\t",newaddr);
+ mdbprintins(*(int *)newaddr, newaddr);
+ }
+ printf("\n# ");
+ }
+ break;
+
+ default:
+ printf("\n-- %s --\n# ",trap_type[cause]);
+ }
+ ssandrun = 0;
+ break_restore();
+
+ while(1) {
+ c = cngetc();
+ switch(c) {
+ case 'T':
+ trapDump("Debugger");
+ break;
+ case 'b':
+ printf("break-");
+ c = cngetc();
+ switch(c) {
+ case 's':
+ printf("set at ");
+ c = gethex(&newaddr, newaddr);
+ if(c != '\e') {
+ set_break(newaddr);
+ }
+ break;
+
+ case 'd':
+ printf("delete at ");
+ c = gethex(&newaddr, newaddr);
+ if(c != '\e') {
+ del_break(newaddr);
+ }
+ break;
+
+ case 'p':
+ printf("print");
+ prt_break();
+ break;
+ }
+ break;
+
+ case 'r':
+ print_regs();
+ break;
+
+ case 'I':
+ printf("Instruction at ");
+ c = gethex(&newaddr, newaddr);
+ while(c != '\e') {
+ printf("\n %08x\t",newaddr);
+ mdbprintins(*(int *)newaddr, newaddr);
+ newaddr += 4;
+ c = cngetc();
+ }
+ break;
+
+ case 'c':
+ printf("continue");
+ if(break_find((int)(mdbpcb.pcb_regs[PC])) >= 0) {
+ ssandrun = 1;
+ mdbsetsstep();
+ }
+ else {
+ break_insert();
+ }
+ return(TRUE);
+ case 'S':
+ printf("Stack traceback:\n");
+ stacktrace();
+ return(TRUE);
+ case 's':
+ set_break(mdbpcb.pcb_regs[PC] + 8);
+ return(TRUE);
+ case ' ':
+ mdbsetsstep();
+ return(TRUE);
+
+ case 'd':
+ printf("dump ");
+ c = gethex(&newaddr, newaddr);
+ if(c == ',') {
+ c = gethex(&size,256);
+ }
+ else {
+ size = 16;
+ }
+ if(c == '\n' && newaddr != 0) {
+ dump((u_int *)newaddr, size);
+ newaddr += size;
+ }
+ break;
+
+ case 'm':
+ printf("mod ");
+ c = gethex(&newaddr, newaddr);
+ while(c == ',') {
+ c = gethex(&size, 0);
+ if(c != '\e')
+ *((u_int *)newaddr)++ = size;
+ }
+ break;
+
+ case 'i':
+ printf("in-");
+ c = cngetc();
+ switch(c) {
+ case 'b':
+ printf("byte ");
+ c = gethex(&newaddr, newaddr);
+ if(c == '\n') {
+ printf("= %02x",
+ *(u_char *)newaddr);
+ }
+ break;
+ case 'h':
+ printf("halfword ");
+ c = gethex(&newaddr, newaddr);
+ if(c == '\n') {
+ printf("= %04x",
+ *(u_short *)newaddr);
+ }
+ break;
+ case 'w':
+ printf("word ");
+ c = gethex(&newaddr, newaddr);
+ if(c == '\n') {
+ printf("= %08x",
+ *(u_int *)newaddr);
+ }
+ break;
+ }
+ break;
+
+ case 'o':
+ printf("out-");
+ c = cngetc();
+ switch(c) {
+ case 'b':
+ printf("byte ");
+ c = gethex(&newaddr, newaddr);
+ if(c == ',') {
+ c = gethex(&size, 0);
+ if(c == '\n') {
+ *(u_char *)newaddr = size;
+ }
+ }
+ break;
+ case 'h':
+ printf("halfword ");
+ c = gethex(&newaddr, newaddr);
+ if(c == ',') {
+ c = gethex(&size, 0);
+ if(c == '\n') {
+ *(u_short *)newaddr = size;
+ }
+ }
+ break;
+ case 'w':
+ printf("word ");
+ c = gethex(&newaddr, newaddr);
+ if(c == ',') {
+ c = gethex(&size, 0);
+ if(c == '\n') {
+ *(u_int *)newaddr = size;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 't':
+ printf("tlb-dump\n");
+ arc_dump_tlb(0,23);
+ (void)cngetc();
+ arc_dump_tlb(24,47);
+ break;
+
+ case 'f':
+ printf("flush-");
+ c = cngetc();
+ switch(c) {
+ case 't':
+ printf("tlb");
+ R4K_TLBFlush(num_tlbentries);
+ break;
+
+ case 'c':
+ printf("cache");
+ R4K_FlushCache();
+ break;
+ }
+ break;
+
+ default:
+ cnputc('\a');
+ break;
+ }
+ printf("\n# ");
+ }
+}
+
+u_int mdb_ss_addr;
+u_int mdb_ss_instr;
+
+static void
+mdbsetsstep()
+{
+ register u_int va;
+ register int *locr0 = mdbpcb.pcb_regs;
+
+ /* compute next address after current location */
+ if(mdbpeek(locr0[PC]) != 0) {
+ va = MipsEmulateBranch(locr0, locr0[PC], 0, mdbpeek(locr0[PC]));
+ }
+ else {
+ va = locr0[PC] + 4;
+ }
+ if (mdb_ss_addr) {
+ printf("mdbsetsstep: breakpoint already set at %x (va %x)\n",
+ mdb_ss_addr, va);
+ return;
+ }
+ mdb_ss_addr = va;
+
+ if ((int)va < 0) {
+ /* kernel address */
+ mdb_ss_instr = mdbpeek(va);
+ mdbpoke(va, BREAK_SSTEP);
+ R4K_FlushDCache(va,4);
+ R4K_FlushICache(va,4);
+ return;
+ }
+}
+
+static int
+mdbclrsstep(int cr)
+{
+ register u_int pc, va;
+ u_int instr;
+
+ /* fix pc if break instruction is in the delay slot */
+ pc = mdbpcb.pcb_regs[PC];
+ if (cr < 0)
+ pc += 4;
+
+ /* check to be sure its the one we are expecting */
+ va = mdb_ss_addr;
+ if (!va || va != pc)
+ return(FALSE);
+
+ /* read break instruction */
+ instr = mdbpeek(va);
+ if (instr != BREAK_SSTEP)
+ return(FALSE);
+
+ if ((int)va < 0) {
+ /* kernel address */
+ mdbpoke(va, mdb_ss_instr);
+ R4K_FlushDCache(va,4);
+ R4K_FlushICache(va,4);
+ mdb_ss_addr = 0;
+ return(TRUE);
+ }
+
+ printf("can't clear break at %x\n", va);
+ mdb_ss_addr = 0;
+ return(FALSE);
+}
+
+
+/* ARGSUSED */
+static int
+mdbprintins(int ins, int mdbdot)
+{
+ InstFmt i;
+ int delay = 0;
+
+ i.word = ins;
+
+ switch (i.JType.op) {
+ case OP_SPECIAL:
+ if (i.word == 0) {
+ printf("nop");
+ break;
+ }
+ if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
+ printf("move\t%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rs]);
+ break;
+ }
+ printf("%s", spec_name[i.RType.func]);
+ switch (i.RType.func) {
+ case OP_SLL:
+ case OP_SRL:
+ case OP_SRA:
+ case OP_DSLL:
+ case OP_DSRL:
+ case OP_DSRA:
+ case OP_DSLL32:
+ case OP_DSRL32:
+ case OP_DSRA32:
+ printf("\t%s,%s,%d",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt],
+ i.RType.shamt);
+ break;
+
+ case OP_SLLV:
+ case OP_SRLV:
+ case OP_SRAV:
+ case OP_DSLLV:
+ case OP_DSRLV:
+ case OP_DSRAV:
+ printf("\t%s,%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rt],
+ reg_name[i.RType.rs]);
+ break;
+
+ case OP_MFHI:
+ case OP_MFLO:
+ printf("\t%s", reg_name[i.RType.rd]);
+ break;
+
+ case OP_JR:
+ case OP_JALR:
+ delay = 1;
+ /* FALLTHROUGH */
+ case OP_MTLO:
+ case OP_MTHI:
+ printf("\t%s", reg_name[i.RType.rs]);
+ break;
+
+ case OP_MULT:
+ case OP_MULTU:
+ case OP_DMULT:
+ case OP_DMULTU:
+ case OP_DIV:
+ case OP_DIVU:
+ case OP_DDIV:
+ case OP_DDIVU:
+ printf("\t%s,%s",
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt]);
+ break;
+
+ case OP_SYSCALL:
+ case OP_SYNC:
+ break;
+
+ case OP_BREAK:
+ printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
+ break;
+
+ default:
+ printf("\t%s,%s,%s",
+ reg_name[i.RType.rd],
+ reg_name[i.RType.rs],
+ reg_name[i.RType.rt]);
+ };
+ break;
+
+ case OP_BCOND:
+ printf("%s\t%s,", bcond_name[i.IType.rt],
+ reg_name[i.IType.rs]);
+ goto pr_displ;
+
+ case OP_BLEZ:
+ case OP_BLEZL:
+ case OP_BGTZ:
+ case OP_BGTZL:
+ printf("%s\t%s,", op_name[i.IType.op],
+ reg_name[i.IType.rs]);
+ goto pr_displ;
+
+ case OP_BEQ:
+ case OP_BEQL:
+ if (i.IType.rs == 0 && i.IType.rt == 0) {
+ printf("b\t");
+ goto pr_displ;
+ }
+ /* FALLTHROUGH */
+ case OP_BNE:
+ case OP_BNEL:
+ printf("%s\t%s,%s,", op_name[i.IType.op],
+ reg_name[i.IType.rs],
+ reg_name[i.IType.rt]);
+ pr_displ:
+ delay = 1;
+ printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
+ break;
+
+ case OP_COP0:
+ switch (i.RType.rs) {
+ case OP_BCx:
+ case OP_BCy:
+ printf("bc0%c\t",
+ "ft"[i.RType.rt & COPz_BC_TF_MASK]);
+ goto pr_displ;
+
+ case OP_MT:
+ printf("mtc0\t%s,%s",
+ reg_name[i.RType.rt],
+ c0_reg[i.RType.rd]);
+ break;
+
+ case OP_DMT:
+ printf("dmtc0\t%s,%s",
+ reg_name[i.RType.rt],
+ c0_reg[i.RType.rd]);
+ break;
+
+ case OP_MF:
+ printf("mfc0\t%s,%s",
+ reg_name[i.RType.rt],
+ c0_reg[i.RType.rd]);
+ break;
+
+ case OP_DMF:
+ printf("dmfc0\t%s,%s",
+ reg_name[i.RType.rt],
+ c0_reg[i.RType.rd]);
+ break;
+
+ default:
+ printf("%s", c0_opname[i.FRType.func]);
+ };
+ break;
+
+ case OP_COP1:
+ switch (i.RType.rs) {
+ case OP_BCx:
+ case OP_BCy:
+ printf("bc1%c\t",
+ "ft"[i.RType.rt & COPz_BC_TF_MASK]);
+ goto pr_displ;
+
+ case OP_MT:
+ printf("mtc1\t%s,f%d",
+ reg_name[i.RType.rt],
+ i.RType.rd);
+ break;
+
+ case OP_MF:
+ printf("mfc1\t%s,f%d",
+ reg_name[i.RType.rt],
+ i.RType.rd);
+ break;
+
+ case OP_CT:
+ printf("ctc1\t%s,f%d",
+ reg_name[i.RType.rt],
+ i.RType.rd);
+ break;
+
+ case OP_CF:
+ printf("cfc1\t%s,f%d",
+ reg_name[i.RType.rt],
+ i.RType.rd);
+ break;
+
+ default:
+ printf("%s.%s\tf%d,f%d,f%d",
+ cop1_name[i.FRType.func],
+ fmt_name[i.FRType.fmt],
+ i.FRType.fd, i.FRType.fs, i.FRType.ft);
+ };
+ break;
+
+ case OP_J:
+ case OP_JAL:
+ printf("%s\t", op_name[i.JType.op]);
+ printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
+ delay = 1;
+ break;
+
+ case OP_LWC1:
+ case OP_SWC1:
+ printf("%s\tf%d,", op_name[i.IType.op],
+ i.IType.rt);
+ goto loadstore;
+
+ case OP_LB:
+ case OP_LH:
+ case OP_LW:
+ case OP_LD:
+ case OP_LBU:
+ case OP_LHU:
+ case OP_LWU:
+ case OP_SB:
+ case OP_SH:
+ case OP_SW:
+ case OP_SD:
+ printf("%s\t%s,", op_name[i.IType.op],
+ reg_name[i.IType.rt]);
+ loadstore:
+ printf("%d(%s)", (short)i.IType.imm,
+ reg_name[i.IType.rs]);
+ break;
+
+ case OP_ORI:
+ case OP_XORI:
+ if (i.IType.rs == 0) {
+ printf("li\t%s,0x%x",
+ reg_name[i.IType.rt],
+ i.IType.imm);
+ break;
+ }
+ /* FALLTHROUGH */
+ case OP_ANDI:
+ printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
+ reg_name[i.IType.rt],
+ reg_name[i.IType.rs],
+ i.IType.imm);
+ break;
+
+ case OP_LUI:
+ printf("%s\t%s,0x%x", op_name[i.IType.op],
+ reg_name[i.IType.rt],
+ i.IType.imm);
+ break;
+
+ case OP_ADDI:
+ case OP_DADDI:
+ case OP_ADDIU:
+ case OP_DADDIU:
+ if (i.IType.rs == 0) {
+ printf("li\t%s,%d",
+ reg_name[i.IType.rt],
+ (short)i.IType.imm);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ printf("%s\t%s,%s,%d", op_name[i.IType.op],
+ reg_name[i.IType.rt],
+ reg_name[i.IType.rs],
+ (short)i.IType.imm);
+ }
+ return(delay);
+}
+
+
+/*
+ * Dump TLB contents.
+ */
+static void
+arc_dump_tlb(int first,int last)
+{
+ int tlbno;
+ struct tlb tlb;
+
+ tlbno = first;
+
+ while(tlbno <= last) {
+ R4K_TLBRead(tlbno, &tlb);
+ if(tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V) {
+ printf("TLB %2d vad 0x%08x ", tlbno, tlb.tlb_hi);
+ }
+ else {
+ printf("TLB*%2d vad 0x%08x ", tlbno, tlb.tlb_hi);
+ }
+ printf("0=0x%08x ", pfn_to_vad(tlb.tlb_lo0));
+ printf("%c", tlb.tlb_lo0 & PG_M ? 'M' : ' ');
+ printf("%c", tlb.tlb_lo0 & PG_G ? 'G' : ' ');
+ printf(" atr %x ", (tlb.tlb_lo0 >> 3) & 7);
+ printf("1=0x%08x ", pfn_to_vad(tlb.tlb_lo1));
+ printf("%c", tlb.tlb_lo1 & PG_M ? 'M' : ' ');
+ printf("%c", tlb.tlb_lo1 & PG_G ? 'G' : ' ');
+ printf(" atr %x ", (tlb.tlb_lo1 >> 3) & 7);
+ printf(" sz=%x\n", tlb.tlb_mask);
+
+ tlbno++;
+ }
+}
diff --git a/sys/arch/mips/mips/process_machdep.c b/sys/arch/mips/mips/process_machdep.c
new file mode 100644
index 00000000000..7a5e2b4d7d0
--- /dev/null
+++ b/sys/arch/mips/mips/process_machdep.c
@@ -0,0 +1,116 @@
+/* $OpenBSD: process_machdep.c,v 1.1 1998/01/28 12:12:09 pefo Exp $ */
+/*
+ * Copyright (c) 1994 Adam Glass
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1993 Jan-Simon Pendry
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * From:
+ * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
+ *
+ * $Id: process_machdep.c,v 1.1 1998/01/28 12:12:09 pefo Exp $
+ */
+
+/*
+ * This file may seem a bit stylized, but that so that it's easier to port.
+ * Functions to be implemented here are:
+ *
+ * process_read_regs(proc, regs)
+ * Get the current user-visible register set from the process
+ * and copy it into the regs structure (<machine/reg.h>).
+ * The process is stopped at the time read_regs is called.
+ *
+ * process_write_regs(proc, regs)
+ * Update the current register set from the passed in regs
+ * structure. Take care to avoid clobbering special CPU
+ * registers or privileged bits in the PSL.
+ * The process is stopped at the time write_regs is called.
+ *
+ * process_sstep(proc)
+ * Arrange for the process to trap after executing a single instruction.
+ *
+ * process_set_pc(proc)
+ * Set the process's program counter.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/vnode.h>
+#include <sys/ptrace.h>
+#include <machine/pte.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+extern void cpu_singlestep __P((struct proc *));
+int
+process_read_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ bcopy((caddr_t)p->p_md.md_regs, (caddr_t)regs, sizeof(struct reg));
+ return (0);
+}
+
+int
+process_write_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ bcopy((caddr_t)regs, (caddr_t)p->p_md.md_regs, sizeof(struct reg));
+/*XXX Clear to user set bits!! */
+ return (0);
+}
+
+int
+process_sstep(p, sstep)
+ struct proc *p;
+{
+ if(sstep)
+ cpu_singlestep(p);
+ return (0);
+}
+
+int
+process_set_pc(p, addr)
+ struct proc *p;
+ caddr_t addr;
+{
+ p->p_md.md_regs[PC] = (int)addr;
+ return (0);
+}
+
diff --git a/sys/arch/mips/mips/sys_machdep.c b/sys/arch/mips/mips/sys_machdep.c
new file mode 100644
index 00000000000..b02d33c3eaf
--- /dev/null
+++ b/sys/arch/mips/mips/sys_machdep.c
@@ -0,0 +1,130 @@
+/* $OpenBSD: sys_machdep.c,v 1.1 1998/01/28 12:12:09 pefo Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)sys_machdep.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/mtio.h>
+#include <sys/buf.h>
+#include <sys/trace.h>
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
+#ifdef TRACE
+int nvualarm;
+
+vtrace(p, uap, retval)
+ struct proc *p;
+ register struct vtrace_args /* {
+ syscallarg(int) request;
+ syscallarg(int) value;
+ } */ *uap;
+ register_t *retval;
+{
+ int vdoualarm();
+
+ switch (SCARG(uap, request)) {
+
+ case VTR_DISABLE: /* disable a trace point */
+ case VTR_ENABLE: /* enable a trace point */
+ if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS)
+ return (EINVAL);
+ *retval = traceflags[SCARG(uap, value)];
+ traceflags[SCARG(uap, value)] = SCARG(uap, request);
+ break;
+
+ case VTR_VALUE: /* return a trace point setting */
+ if (SCARG(uap, value) < 0 || SCARG(uap, value) >= TR_NFLAGS)
+ return (EINVAL);
+ *retval = traceflags[SCARG(uap, value)];
+ break;
+
+ case VTR_UALARM: /* set a real-time ualarm, less than 1 min */
+ if (SCARG(uap, value) <= 0 || SCARG(uap, value) > 60 * hz ||
+ nvualarm > 5)
+ return (EINVAL);
+ nvualarm++;
+ timeout(vdoualarm, (caddr_t)p->p_pid, SCARG(uap, value));
+ break;
+
+ case VTR_STAMP:
+ trace(TR_STAMP, SCARG(uap, value), p->p_pid);
+ break;
+ }
+ return (0);
+}
+
+vdoualarm(arg)
+ int arg;
+{
+ register struct proc *p;
+
+ p = pfind(arg);
+ if (p)
+ psignal(p, 16);
+ nvualarm--;
+}
+#endif
+
+int
+sys_sysarch(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_sysarch_args /* {
+ syscallarg(int) op;
+ syscallarg(char *) parms;
+ } */ *uap = v;
+ int error = 0;
+
+ switch(SCARG(uap, op)) {
+ default:
+ error = EINVAL;
+ break;
+ }
+ return(error);
+}