diff options
author | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-01-28 12:12:10 +0000 |
---|---|---|
committer | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-01-28 12:12:10 +0000 |
commit | d2d2a72135a2801084e26a82991316e8a3f4afbf (patch) | |
tree | 99aff6458f5009611a9e4c476a54175bf9ae8085 /sys/arch/mips | |
parent | e132fd998366d8d693ef08f870464d6dafc9232b (diff) |
First set of Mips mi files.
Diffstat (limited to 'sys/arch/mips')
-rw-r--r-- | sys/arch/mips/mips/arcbios.c | 332 | ||||
-rw-r--r-- | sys/arch/mips/mips/clock.c | 360 | ||||
-rw-r--r-- | sys/arch/mips/mips/cpu.c | 207 | ||||
-rw-r--r-- | sys/arch/mips/mips/cpu_ecoff.c | 92 | ||||
-rw-r--r-- | sys/arch/mips/mips/disksubr.c | 523 | ||||
-rw-r--r-- | sys/arch/mips/mips/mainbus.c | 191 | ||||
-rw-r--r-- | sys/arch/mips/mips/mem.c | 180 | ||||
-rw-r--r-- | sys/arch/mips/mips/minidebug.c | 953 | ||||
-rw-r--r-- | sys/arch/mips/mips/process_machdep.c | 116 | ||||
-rw-r--r-- | sys/arch/mips/mips/sys_machdep.c | 130 |
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); +} |