summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 12:32:30 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 12:32:30 +0000
commit75194bc95893b936e017a7a76f40580a4f1b63e5 (patch)
treed6c782e3b866a549d8e8a6131793b5ed7aba1a1d /sys
parent91ed62167d774d2d4540b530093d0c45e835ac28 (diff)
moved from m88k directory
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/mvme88k/mvme88k/clock.c483
-rw-r--r--sys/arch/mvme88k/mvme88k/continuation.s241
-rw-r--r--sys/arch/mvme88k/mvme88k/exception_return.s258
-rw-r--r--sys/arch/mvme88k/mvme88k/locore2.c99
-rw-r--r--sys/arch/mvme88k/mvme88k/m1x7_init.c205
-rw-r--r--sys/arch/mvme88k/mvme88k/misc.s67
6 files changed, 1353 insertions, 0 deletions
diff --git a/sys/arch/mvme88k/mvme88k/clock.c b/sys/arch/mvme88k/mvme88k/clock.c
new file mode 100644
index 00000000000..ec5563e443e
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/clock.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ *
+ * @(#)clock.c 8.1 (Berkeley) 6/11/93
+ *
+ * from: Header: clock.c,v 1.17 92/11/26 03:04:47 torek Exp (LBL)
+ * $Id: clock.c,v 1.1 1995/10/18 12:32:18 deraadt Exp $
+ */
+
+/*
+ * Clock driver. This is the id prom (``eeprom'') driver as well
+ * and includes the timer register functions too.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#ifdef GPROF
+#include <sys/gmon.h>
+#endif
+
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+
+#include <sparc/sparc/clockreg.h>
+#include <sparc/sparc/intreg.h>
+#include <sparc/sparc/timerreg.h>
+
+/*
+ * Statistics clock interval and variance, in usec. Variance must be a
+ * power of two. Since this gives us an even number, not an odd number,
+ * we discard one case and compensate. That is, a variance of 1024 would
+ * give us offsets in [0..1023]. Instead, we take offsets in [1..1023].
+ * This is symmetric about the point 512, or statvar/2, and thus averages
+ * to that value (assuming uniform random numbers).
+ */
+/* XXX fix comment to match value */
+int statvar = 8192;
+int statmin; /* statclock interval - 1/2*variance */
+
+static int clockmatch __P((struct device *, struct cfdata *, void *));
+static void clockattach __P((struct device *, struct device *, void *));
+
+struct cfdriver clockcd =
+ { NULL, "clock", clockmatch, clockattach, DV_DULL, sizeof(struct device) };
+
+static int timermatch __P((struct device *, struct cfdata *, void *));
+static void timerattach __P((struct device *, struct device *, void *));
+struct cfdriver timercd =
+ { NULL, "timer", timermatch, timerattach, DV_DULL, sizeof(struct device) };
+
+/*
+ * The OPENPROM calls the clock the "eeprom", so we have to have our
+ * own special match function to call it the "clock".
+ */
+static int
+clockmatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+
+ return (strcmp("eeprom", ((struct romaux *)aux)->ra_name) == 0);
+}
+
+/* ARGSUSED */
+static void
+clockattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ register int h;
+ register struct clockreg *cl;
+ struct romaux *ra = aux;
+ char *prop;
+
+ prop = getpropstring(ra->ra_node, "model");
+ printf(": %s (eeprom)\n", prop);
+ /*
+ * We ignore any existing virtual address as we need to map
+ * this read-only and make it read-write only temporarily,
+ * whenever we read or write the clock chip. The clock also
+ * contains the ID ``PROM'', and I have already had the pleasure
+ * of reloading the cpu type, Ethernet address, etc, by hand from
+ * the console FORTH interpreter. I intend not to enjoy it again.
+ */
+ if (strcmp(prop, "mk48t08") == 0) {
+ /*
+ * the MK48T08 is 8K
+ */
+ cl = (struct clockreg *)mapiodev(ra->ra_paddr, 2 * NBPG);
+ pmap_changeprot(kernel_pmap, (vm_offset_t)cl, VM_PROT_READ, 1);
+ pmap_changeprot(kernel_pmap, (vm_offset_t)cl + NBPG, VM_PROT_READ, 1);
+ cl = (struct clockreg *)((int)cl + CLK_MK48T08_OFF);
+ } else {
+ /*
+ * the MK48T02 is 2K
+ */
+ cl = (struct clockreg *)mapiodev(ra->ra_paddr, sizeof *clockreg);
+ pmap_changeprot(kernel_pmap, (vm_offset_t)cl, VM_PROT_READ, 1);
+ }
+
+ h = cl->cl_idprom.id_machine << 24;
+ h |= cl->cl_idprom.id_hostid[0] << 16;
+ h |= cl->cl_idprom.id_hostid[1] << 8;
+ h |= cl->cl_idprom.id_hostid[2];
+ hostid = h;
+ clockreg = cl;
+}
+
+/*
+ * The OPENPROM calls the timer the "counter-timer".
+ */
+static int
+timermatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+
+ return (strcmp("counter-timer", ((struct romaux *)aux)->ra_name) == 0);
+}
+
+/* ARGSUSED */
+static void
+timerattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ register struct romaux *ra = aux;
+
+ printf("\n");
+ /*
+ * This time, we ignore any existing virtual address because
+ * we have a fixed virtual address for the timer, to make
+ * microtime() faster.
+ */
+ (void)mapdev(ra->ra_paddr, TIMERREG_VA, sizeof(struct timerreg));
+ /* should link interrupt handlers here, rather than compiled-in? */
+}
+
+/*
+ * Write en/dis-able clock registers. We coordinate so that several
+ * writers can run simultaneously.
+ */
+void
+clk_wenable(onoff)
+ int onoff;
+{
+ register int s;
+ register vm_prot_t prot;/* nonzero => change prot */
+ static int writers;
+
+ s = splhigh();
+ if (onoff)
+ prot = writers++ == 0 ? VM_PROT_READ|VM_PROT_WRITE : 0;
+ else
+ prot = --writers == 0 ? VM_PROT_READ : 0;
+ splx(s);
+ if (prot)
+ pmap_changeprot(kernel_pmap, (vm_offset_t)clockreg, prot, 1);
+}
+
+/*
+ * XXX this belongs elsewhere
+ */
+void
+myetheraddr(cp)
+ u_char *cp;
+{
+ register struct clockreg *cl = clockreg;
+
+ cp[0] = cl->cl_idprom.id_ether[0];
+ cp[1] = cl->cl_idprom.id_ether[1];
+ cp[2] = cl->cl_idprom.id_ether[2];
+ cp[3] = cl->cl_idprom.id_ether[3];
+ cp[4] = cl->cl_idprom.id_ether[4];
+ cp[5] = cl->cl_idprom.id_ether[5];
+}
+
+/*
+ * Delay: wait for `about' n microseconds to pass.
+ * This is easy to do on the SparcStation since we have
+ * freerunning microsecond timers -- no need to guess at
+ * cpu speed factors. We just wait for it to change n times
+ * (if we calculated a limit, we might overshoot, and precision
+ * is irrelevant here---we want less object code).
+ */
+delay(n)
+ register int n;
+{
+ register int c, t;
+
+ if (timercd.cd_ndevs == 0)
+ panic("delay");
+ c = TIMERREG->t_c10.t_counter;
+ while (--n >= 0) {
+ while ((t = TIMERREG->t_c10.t_counter) == c)
+ continue;
+ c = t;
+ }
+}
+
+/*
+ * Set up the real-time and statistics clocks. Leave stathz 0 only if
+ * no alternative timer is available.
+ *
+ * The frequencies of these clocks must be an even number of microseconds.
+ */
+cpu_initclocks()
+{
+ register int statint, minint;
+
+ if (1000000 % hz) {
+ printf("cannot get %d Hz clock; using 100 Hz\n", hz);
+ hz = 100;
+ tick = 1000000 / hz;
+ }
+ if (stathz == 0)
+ stathz = hz;
+ if (1000000 % stathz) {
+ printf("cannot get %d Hz statclock; using 100 Hz\n", stathz);
+ stathz = 100;
+ }
+ profhz = stathz; /* always */
+
+ statint = 1000000 / stathz;
+ minint = statint / 2 + 100;
+ while (statvar > minint)
+ statvar >>= 1;
+ TIMERREG->t_c10.t_limit = tmr_ustolim(tick);
+ TIMERREG->t_c14.t_limit = tmr_ustolim(statint);
+ statmin = statint - (statvar >> 1);
+ ienab_bis(IE_L14 | IE_L10);
+}
+
+/*
+ * Dummy setstatclockrate(), since we know profhz==hz.
+ */
+/* ARGSUSED */
+void
+setstatclockrate(newhz)
+ int newhz;
+{
+ /* nothing */
+}
+
+/*
+ * Clock interrupts.
+ */
+int
+clockintr(cap)
+ void *cap;
+{
+ volatile register unsigned char icr;
+ /* clear clock interrupt */
+ asm ("ld.b %0,%1" : "=r" (icr) : "" (TIMER2ICR));
+ icr |= ICLR;
+ asm ("st.b %0,%1" : "=r" (icr) : "" (TIMER2ICR));
+
+ /* read the limit register to clear the interrupt */
+ hardclock((struct clockframe *)cap);
+
+ return (1);
+}
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10))
+
+#define SECDAY (24 * 60 * 60)
+#define SECYR (SECDAY * 365)
+#define LEAPYEAR(y) (((y) & 3) == 0)
+
+/*
+ * This code is defunct after 2068.
+ * Will Unix still be here then??
+ */
+const short dayyr[12] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+chiptotime(sec, min, hour, day, mon, year)
+ register int sec, min, hour, day, mon, year;
+{
+ register int days, yr;
+
+ sec = FROMBCD(sec);
+ min = FROMBCD(min);
+ hour = FROMBCD(hour);
+ day = FROMBCD(day);
+ mon = FROMBCD(mon);
+ year = FROMBCD(year) + YEAR0;
+
+ /* simple sanity checks */
+ if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31)
+ return (0);
+ days = 0;
+ for (yr = 70; yr < year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[mon - 1] + day - 1;
+ if (LEAPYEAR(yr) && mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ return (days * SECDAY + hour * 3600 + min * 60 + sec);
+}
+
+struct chiptime {
+ int sec;
+ int min;
+ int hour;
+ int wday;
+ int day;
+ int mon;
+ int year;
+};
+
+timetochip(c)
+ register struct chiptime *c;
+{
+ register int t, t2, t3, now = time.tv_sec;
+
+ /* compute the year */
+ t2 = now / SECDAY;
+ t3 = (t2 + 2) % 7; /* day of week */
+ c->wday = TOBCD(t3 + 1);
+
+ t = 69;
+ while (t2 >= 0) { /* whittle off years */
+ t3 = t2;
+ t++;
+ t2 -= LEAPYEAR(t) ? 366 : 365;
+ }
+ c->year = t;
+
+ /* t3 = month + day; separate */
+ t = LEAPYEAR(t);
+ for (t2 = 1; t2 < 12; t2++)
+ if (t3 < dayyr[t2] + (t && t2 > 1))
+ break;
+
+ /* t2 is month */
+ c->mon = t2;
+ c->day = t3 - dayyr[t2 - 1] + 1;
+ if (t && t2 > 2)
+ c->day--;
+
+ /* the rest is easy */
+ t = now % SECDAY;
+ c->hour = t / 3600;
+ t %= 3600;
+ c->min = t / 60;
+ c->sec = t % 60;
+
+ c->sec = TOBCD(c->sec);
+ c->min = TOBCD(c->min);
+ c->hour = TOBCD(c->hour);
+ c->day = TOBCD(c->day);
+ c->mon = TOBCD(c->mon);
+ c->year = TOBCD(c->year - YEAR0);
+}
+
+/*
+ * Set up the system's time, given a `reasonable' time value.
+ */
+inittodr(base)
+ time_t base;
+{
+ register struct clockreg *cl = clockreg;
+ int sec, min, hour, day, mon, year;
+ int badbase = 0, waszero = base == 0;
+
+ if (base < 5 * SECYR) {
+ /*
+ * If base is 0, assume filesystem time is just unknown
+ * in stead of preposterous. Don't bark.
+ */
+ if (base != 0)
+ printf("WARNING: preposterous time in file system\n");
+ /* not going to use it anyway, if the chip is readable */
+ base = 21*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ }
+ clk_wenable(1);
+ cl->cl_csr |= CLK_READ; /* enable read (stop time) */
+ sec = cl->cl_sec;
+ min = cl->cl_min;
+ hour = cl->cl_hour;
+ day = cl->cl_mday;
+ mon = cl->cl_month;
+ year = cl->cl_year;
+ cl->cl_csr &= ~CLK_READ; /* time wears on */
+ clk_wenable(0);
+ if ((time.tv_sec = chiptotime(sec, min, hour, day, mon, year)) == 0) {
+ printf("WARNING: bad date in battery clock");
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the clock.
+ */
+ time.tv_sec = base;
+ if (!badbase)
+ resettodr();
+ } else {
+ int deltat = time.tv_sec - base;
+
+ if (deltat < 0)
+ deltat = -deltat;
+ if (waszero || deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+ }
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the clock based on the current time.
+ * Used when the current clock is preposterous, when the time is changed,
+ * and when rebooting. Do nothing if the time is not yet known, e.g.,
+ * when crashing during autoconfig.
+ */
+resettodr()
+{
+ register struct clockreg *cl;
+ struct chiptime c;
+
+ if (!time.tv_sec || (cl = clockreg) == NULL)
+ return;
+ timetochip(&c);
+ clk_wenable(1);
+ cl->cl_csr |= CLK_WRITE; /* enable write */
+ cl->cl_sec = c.sec;
+ cl->cl_min = c.min;
+ cl->cl_hour = c.hour;
+ cl->cl_wday = c.wday;
+ cl->cl_mday = c.day;
+ cl->cl_month = c.mon;
+ cl->cl_year = c.year;
+ cl->cl_csr &= ~CLK_WRITE; /* load them up */
+ clk_wenable(0);
+}
diff --git a/sys/arch/mvme88k/mvme88k/continuation.s b/sys/arch/mvme88k/mvme88k/continuation.s
new file mode 100644
index 00000000000..4149ebd06d1
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/continuation.s
@@ -0,0 +1,241 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * 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 Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Assembler continuation support routines.
+ */
+/*
+ * HISTORY
+ * $Log: continuation.s,v $
+ * Revision 1.1 1995/10/18 12:32:20 deraadt
+ * moved from m88k directory
+ *
+ * Revision 1.1.1.1 1995/10/18 10:54:27 deraadt
+ * initial 88k import; code by nivas and based on mach luna88k
+ *
+ * Revision 2.7 93/01/26 18:00:29 danner
+ * changed ;comments to C-style for cpp.
+ * [93/01/25 jfriedl]
+ *
+ * Revision 2.6 93/01/14 17:53:09 danner
+ * Enhanced debugger support for continuations.
+ * [92/12/02 jfriedl]
+ *
+ * Revision 2.5 92/08/03 17:51:54 jfriedl
+ * Adjusted references from luna88k/locore --> luna88k
+ * [92/07/24 jfriedl]
+ *
+ * Revision 2.4.1.1 92/05/27 14:48:42 danner
+ * Updated includes.
+ * PSR_INTERRUPT_DISABLE_BIT -> PSR_IND_LOG
+ *
+ *
+ * Revision 2.4 92/05/04 11:27:58 danner
+ * Support for gcc 2.x's moptimize-arg-area switch. Simplify
+ * Switch_context.
+ * [92/05/03 danner]
+ * Performed instruction reordering in Switch_context suggested by
+ * jfriedl.
+ * [92/04/26 danner]
+ * [92/04/12 16:24:48 danner]
+ *
+ * Thread_syscall_return now stores r2 into the pcb. This cannot be
+ * avoided due to asts.
+ * [92/04/12 danner]
+ *
+ * Revision 2.3 92/03/03 15:38:44 rpd
+ * Save continuation argument as old_thread->swap_func in
+ * Switch_context.
+ * [92/03/02 danner]
+ *
+ * Added missing stcr in interrupt disabling code.
+ * [92/03/02 danner]
+ *
+ * Revision 2.2 92/02/18 18:03:27 elf
+ * Created.
+ * [92/02/01 danner]
+ *
+ */
+#ifndef ASSEMBLER /* predefined by ascpp, at least */
+#define ASSEMBLER /* this is required for some of the include files */
+#endif
+
+#include <assym.s> /* for PCB_KSP, etc */
+#include <machine/asm.h>
+#include <motorola/m88k/m88100/m88100.h>
+#include <motorola/m88k/m88100/psl.h>
+#include <mach/machine/vm_param.h>
+#include <mach_kdb.h>
+
+/*
+ * Jump out into user space for the first time.
+ * No ast check. Reload registers from continuation,
+ * the jump out.
+ */
+ENTRY(thread_bootstrap_return)
+/*
+ * Jump out to user space from an exception. Restore
+ * all registers.
+ *
+ */
+ENTRY(thread_exception_return)
+ ldcr r30, SR0 /* get current thread pointer */
+ ld r30, r30, THREAD_PCB /* get the pcb pointer */
+ br.n _return_from_exception
+ addu r30, r30, PCB_USER /* point to exception frame */
+
+/*
+ *
+ * Return to user space from a system call.
+ * The value in r2 is the return value, and should be
+ * preserved. The other argument registers (r3-r9), as well as
+ * the temporary registers (r10-r13) need not be restored.
+ * R2 is saved into the pcb in case we get blocked by an ast.
+ */
+ENTRY(thread_syscall_return)
+ ldcr r30, SR0 /* get current thread pointer */
+ ld r30, r30, THREAD_PCB /* get the pcb pointer */
+ addu r30, r30, PCB_USER /* point to exception frame */
+ br.n _return_from_syscall
+ st r2, r30, GENREG_OFF(2) /* save r2 */
+
+
+/*
+ * Call continuation - call the function specified (r2) with no
+ * arguments. Reset the stack point to the top of stack first.
+ * On the 88k, we leave the top 2 words of the stack availible
+ * to hold a pointer to the user exception frame.
+ */
+ENTRY(call_continuation)
+ /* reset the stack pointer to the top of stack. Since stacks
+ grow down, this can be accomplished by rounding up the sp
+ to the nearest KERNEL_STACK_SIZE quanta. We do this
+ carefully to make sure we have a valid stack pointer at
+ all times (in case we take an interrupt).
+ 32 bytes is also subtracted from the stack pointer to
+ allow compilation with gcc 2.x's -moptimize-arg-area
+ option
+ */
+ or r3, r0, KERNEL_STACK_SIZE-1
+ addu r30, r31, r3 /* nsp += KSS-1 */
+ and.c r30, r30, r3 /* nsp &= ~(KSS-1) */
+#if MACH_KDB
+ or r1, r1, 1 /* mark "continuation" return */
+#endif
+ jmp.n r2 /* call continuation */
+ subu r31, r30, (8+32) /* sp = nsp-8 */
+
+/*
+ * Assembler support for switch context. The address space switch
+ * has already occured.
+ *
+ * On entry
+ * r2 - old thread (current_thread)
+ * r3 - continuation for old thread
+ * r4 - new thread
+ * r5 - &(old->pcb->kernel_state)
+ * r6 - &(new->pcb->kernel_state)
+ *
+ */
+ENTRY(Switch_context)
+ /*
+ * if a nonnull continuation, we can skip saving the
+ * current thread state
+ */
+ bcnd ne0, r3, 1f /* non null continuation */
+ /* null continuation; need to save registers */
+ or r11, r0, r5
+ /* save the relevant registers; r1, r14-r31 */
+ st r1, r11,0
+ st r14,r11,4
+ st r15,r11,2*4
+ st r16,r11,3*4
+ st r17,r11,4*4
+ st r18,r11,5*4
+ st r19,r11,6*4
+ st r20,r11,7*4
+ st r21,r11,8*4
+ st r22,r11,9*4
+ st r23,r11,10*4
+ st r24,r11,11*4
+ st r25,r11,12*4
+ /* In principle, registers 26-29 are never manipulated in the
+ kernel. Maybe we can skip saving them? */
+ st r26,r11,13*4
+ st r27,r11,14*4
+ st r28,r11,15*4
+ st r29,r11,16*4
+ st r30,r11,17*4 /* save frame pointer */
+ st r31,r11,18*4 /* save stack pointer */
+ 1:
+ /*
+ Saved incoming thread registers, if necessary.
+ Reload new thread registers
+ */
+ /* get pointer to new pcb */
+ or r11, r0, r6
+ /* switch stacks */
+ ld r31,r11,18*4
+
+ /*
+ current_thread, active_threads and active_stacks have
+ all been updated in switch_context. We just switched
+ onto this threads stack, so all state is now consistent
+ again. Hence its safe to turn interrupts back on */
+
+ /* reenable interrupts */
+ ldcr r10, PSR
+ clr r10, r10, 1<PSR_IND_LOG>
+ stcr r10, PSR
+ FLUSH_PIPELINE
+
+ /* restore registers */
+ ld r1, r11,0
+ ld r14,r11,4
+ ld r15,r11,2*4
+ ld r16,r11,3*4
+ ld r17,r11,4*4
+ ld r18,r11,5*4
+ ld r19,r11,6*4
+ ld r20,r11,7*4
+ ld r21,r11,8*4
+ ld r22,r11,9*4
+ ld r23,r11,10*4
+ ld r24,r11,11*4
+ ld r25,r11,12*4
+ ld r26,r11,13*4
+ ld r27,r11,14*4
+ ld r28,r11,15*4
+ ld r29,r11,16*4
+ /* make the call - r2 is still old thread, which
+ * makes it the return value/first argument
+ * Sometimes this call will be actually be a return
+ * up to switch_context, and sometimes it will be
+ * an actual call to a function. Stare at Figure 4
+ * of Draves, et al. SOSP paper for a few hours to really
+ * understand....
+ */
+ jmp.n r1
+ ld r30,r11,17*4
diff --git a/sys/arch/mvme88k/mvme88k/exception_return.s b/sys/arch/mvme88k/mvme88k/exception_return.s
new file mode 100644
index 00000000000..e770248f522
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/exception_return.s
@@ -0,0 +1,258 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * 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 Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Exception handler return routines.
+ */
+/*
+ * HISTORY
+ * $Log: exception_return.s,v $
+ * Revision 1.1 1995/10/18 12:32:22 deraadt
+ * moved from m88k directory
+ *
+ * Revision 1.1.1.1 1995/10/18 10:54:27 deraadt
+ * initial 88k import; code by nivas and based on mach luna88k
+ *
+ * Revision 2.6 93/01/26 18:00:53 danner
+ * conditionalized define of ASSEMBLER.
+ * [93/01/22 jfriedl]
+ *
+ * Revision 2.5 92/08/03 17:51:58 jfriedl
+ * Update includes, changed to new style manifiest constants [danner]
+ *
+ * Revision 2.4 92/05/04 11:28:03 danner
+ * Remove debugging cruft. Leave argument save area in call to
+ * ast_taken.
+ * [92/05/03 danner]
+ * Remove debugging cruft.
+ * [92/04/12 danner]
+ * [92/04/12 16:25:32 danner]
+ *
+ * In the case of an ast on a return from exception, a random value
+ * was stored into R2. Fixed.
+ * [92/04/12 danner]
+ *
+ * Revision 2.3 92/04/01 10:56:17 rpd
+ * Corrections to the ast handling code.
+ * [92/03/20 danner]
+ * Corrected typo in ast_taken register reload code.
+ * [92/03/03 danner]
+ *
+ * Revision 2.2 92/02/18 18:03:30 elf
+ * Created.
+ * [92/02/01 danner]
+ *
+ */
+
+#include <mach_kdb.h>
+
+#ifndef ASSEMBLER
+# define ASSEMBLER /* this is required for some of the include files */
+#endif
+
+#include <assym.s> /* for PCB_KSP, etc */
+#include <machine/asm.h>
+#include <motorola/m88k/m88100/m88100.h>
+#include <motorola/m88k/m88100/psl.h>
+#include <motorola/m88k/trap.h> /* for T_ defines */
+
+/*
+ * Return from exception - all registers need to be restored.
+ * R30 points to the exception frame.
+ * R31 is the kernel stack pointer.
+ * Any interrupt status is acceptable on entry.
+ * All other registers are scratch.
+ * Any data and fp faults must be cleared up before this routine
+ * is called.
+ */
+ENTRY(return_from_exception)
+ ld r10, r30, REG_OFF(EF_EPSR) ; get old epsr
+ ldcr r2, PSR
+ set r2, r2, 1<PSR_IND_LOG>
+ stcr r2, PSR ; disable interrupts
+ FLUSH_PIPELINE
+ bb1 PSR_IND_LOG, r10, 1f ; no need to check
+ bsr ast_check
+1:
+/* current status -
+
+ interrupts disabled. Asts checked for.
+ Ready to restore registers and return from the exception.
+ R30 points to the exception frame.
+*/
+ /* reload r2-r13 */
+ ld.d r2 , r30, GENREG_OFF(2)
+ ld.d r4 , r30, GENREG_OFF(4)
+ ld.d r6 , r30, GENREG_OFF(6)
+ ld.d r8 , r30, GENREG_OFF(8)
+ ld.d r10, r30, GENREG_OFF(10)
+ br.n return_common
+ ld.d r12, r30, GENREG_OFF(12)
+
+/*
+ * Return from syscall - registers r3-r13 need not be restored.
+ * R30 points to the exception frame.
+ * R31 is the kernel stack pointer.
+ * All other registers are scratch.
+ * Any interrupt status is acceptable on entry.
+ */
+
+ENTRY(return_from_syscall)
+/* turn off interrupts, check ast */
+ ldcr r3, PSR
+ set r3, r3, 1<PSR_IND_LOG>
+ stcr r3, PSR ; disable interrupts
+ FLUSH_PIPELINE
+ bsr ast_check
+ /* restore r2 */
+ ld r2, r30, GENREG_OFF(2)
+ /* current status -
+ interrupts disabled. Asts checked for.
+ Ready to restore registers and return from the exception.
+ R30 holds the frame pointer
+ */
+ /* br return_common */
+
+
+LABEL(return_common)
+/*
+ R30 points to the exception frame.
+ Interrupts off.
+ r2-r13 need to be preserved.
+*/
+ /* restore r14-r29 */
+ ld.d r14, r30, GENREG_OFF(14)
+ ld.d r16, r30, GENREG_OFF(16)
+ ld.d r18, r30, GENREG_OFF(18)
+ ld.d r20, r30, GENREG_OFF(20)
+ ld.d r22, r30, GENREG_OFF(22)
+ ld.d r24, r30, GENREG_OFF(24)
+ ld.d r26, r30, GENREG_OFF(26)
+ ld.d r28, r30, GENREG_OFF(28)
+ ; restore r1, r30, r31 later
+ /* turn off shadowing - we are about to trash
+ our kernel stack pointer, which means this code
+ cannot be tracked by a debuuger */
+ ; disable shadowing (interrupts already disabled above)
+ ldcr r1, PSR
+ set r1, r1, 1<PSR_SFRZ_LOG>
+ stcr r1, PSR
+ FLUSH_PIPELINE
+
+ ; reload the control regs
+ /*
+ * Note: no need to restore the SXIP.
+ * When the "rte" causes execution to continue
+ * first with the instruction pointed to by the NIP
+ * and then the FIP.
+ *
+ * See MC88100 Risc Processor User's Manual, 2nd Edition,
+ * section 6.4.3.1.2-4
+ */
+ ld r31, r30, REG_OFF(EF_SNIP)
+ ld r1, r30, REG_OFF(EF_SFIP)
+ stcr r0, SSBR
+ stcr r31, SNIP
+ stcr r1, SFIP
+
+ ld r31, r30, REG_OFF(EF_EPSR)
+ ld r1, r30, REG_OFF(EF_MODE)
+ stcr r31, EPSR
+
+ /*
+ * restore the mode (cpu flags).
+ * This can't be done directly, because the flags include the
+ * CPU number. We might now be on a different CPU from when we
+ * first entered the exception handler (due to having been blocked
+ * and then restarted on a different CPU). Thus, we'll grab the
+ * old flags and put the current cpu number there.
+ */
+ clr r1, r1, FLAG_CPU_FIELD_WIDTH <0> /* clear bits 0..WIDTH */
+ ldcr r31, SR1
+ clr r31, r31, 0<FLAG_CPU_FIELD_WIDTH> /* clear bits WIDTH..31 */
+ or r31, r1, r31
+ stcr r31, SR1 ; restore old flags with (maybe new) CPU number
+
+ /* Now restore r1, r30, and r31 */
+ ld r1, r30, GENREG_OFF(1)
+ ld.d r30, r30, GENREG_OFF(30)
+
+ _LABEL(return_from_exception)
+ RTE
+
+
+LABEL(ast_check)
+ /* enter here with interrupts disabled */
+ /*
+ *
+ * ast_check:
+ *
+ * if (exception was from user mode && need_ast[cpu_number()])
+ * {
+ * call: ast_taken()(turns interrupts back on,clears need_ast)
+ * disable_interrupts
+ * goto check_ast
+ * }
+ * return (with interrupts off)
+ *
+ * Upon entry,
+ * R30 is the exception frame pointer
+ * R31 is the kernel stack pointer
+ * R1 is the return address
+ *
+ * Upon entry to this function, all user register state
+ * must be up to date in the pcb. In particular, the return
+ * value for thread_syscall_return has to have been saved.
+ *
+ * If we block, we will return through thread_exception_return.
+ *
+ * This routine clobbers r2-r29.
+ *
+ */
+ ld r3, r30, REG_OFF(EF_EPSR)
+ bb1 PSR_MODE_LOG, r3, 1f
+ ldcr r3, SR1
+ mak r3, r3, FLAG_CPU_FIELD_WIDTH <2> ; r3 = cpu#
+ or.u r3, r3, hi16(_need_ast)
+ ld r4, r3, lo16(_need_ast) ; r4 now need_ast[cpu#]
+ bcnd eq0, r4, 1f
+ /* preserve r1, r30 */
+ subu r31, r31, 40
+ st r1, r31, 32
+ bsr.n _ast_taken ; no arguments
+ st r30, r31, 36
+ /* turn interrupts back off */
+ ldcr r1, PSR ; get current PSR
+ set r1, r1, 1<PSR_IND_LOG> ; set for disable intr.
+ stcr r1, PSR ; install new PSR
+ FLUSH_PIPELINE
+ /* restore register state */
+ ld r30, r31, 36
+ ld r1, r31, 32
+ br.n ast_check ; check again
+ addu r31, r31, 40
+1:
+ /* no ast. Return back to caller */
+ jmp r1
diff --git a/sys/arch/mvme88k/mvme88k/locore2.c b/sys/arch/mvme88k/mvme88k/locore2.c
new file mode 100644
index 00000000000..f5800508126
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/locore2.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ *
+ * @(#)locore2.c 8.4 (Berkeley) 12/10/93
+ *
+ * from: Header: locore2.c,v 1.8 92/11/26 03:05:01 mccanne Exp (LBL)
+ * $Id: locore2.c,v 1.1 1995/10/18 12:32:24 deraadt Exp $
+ */
+
+/*
+ * Primitives which are in locore.s on other machines,
+ * but which have no reason to be assembly-coded on SPARC.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+
+int whichqs;
+
+/*
+ * Put process p on the run queue indicated by its priority.
+ * Calls should be made at splstatclock(), and p->p_stat should be SRUN.
+ */
+void
+setrunqueue(p)
+ register struct proc *p;
+{
+ register struct prochd *q;
+ register struct proc *oldlast;
+ register int which = p->p_priority >> 2;
+
+ if (p->p_back != NULL)
+ panic("setrunqueue");
+ q = &qs[which];
+ whichqs |= 1 << which;
+ p->p_forw = (struct proc *)q;
+ p->p_back = oldlast = q->ph_rlink;
+ q->ph_rlink = p;
+ oldlast->p_forw = p;
+}
+
+/*
+ * Remove process p from its run queue, which should be the one
+ * indicated by its priority. Calls should be made at splstatclock().
+ */
+remrq(p)
+ register struct proc *p;
+{
+ register int which = p->p_priority >> 2;
+ register struct prochd *q;
+
+ if ((whichqs & (1 << which)) == 0)
+ panic("remrq");
+ p->p_forw->p_back = p->p_back;
+ p->p_back->p_forw = p->p_forw;
+ p->p_back = NULL;
+ q = &qs[which];
+ if (q->ph_link == (struct proc *)q)
+ whichqs &= ~(1 << which);
+}
diff --git a/sys/arch/mvme88k/mvme88k/m1x7_init.c b/sys/arch/mvme88k/mvme88k/m1x7_init.c
new file mode 100644
index 00000000000..705221fc098
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/m1x7_init.c
@@ -0,0 +1,205 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * All Rights Reserved.
+ *
+ * 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 AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM 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.
+ */
+/*
+ * HISTORY
+ */
+
+/*
+ * Basic initialization for vme187.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+#include <vm/pmap.h>
+#include <machine/vmparam.h>
+#include <machine/cpu.h>
+#include <machine/bug.h>
+
+#define INITIAL_MHZ_GUESS 25.0
+
+struct bugenv bugargs;
+struct kernel{
+ void *entry;
+ void *symtab;
+ void *esym;
+ int bflags;
+ int bdev;
+ char *kname;
+ void *smini;
+ void *emini;
+ void *end_load;
+}kflags;
+char *esym;
+
+int boothowto; /* read in kern/bootstrap */
+int machineid;
+
+#ifndef roundup
+#define roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1))
+#endif /* roundup */
+
+vm_size_t mem_size;
+vm_size_t rawmem_size;
+vm_offset_t first_addr = 0;
+vm_offset_t last_addr = 0;
+
+vm_offset_t avail_start, avail_next, avail_end;
+vm_offset_t virtual_avail, virtual_end;
+
+void *end_loaded;
+int bootdev;
+int no_symbols;
+vm_offset_t miniroot;
+
+struct proc *lastproc;
+pcb_t curpcb;
+
+void cmmu_init(void);
+
+double cycles_per_microsecond = INITIAL_MHZ_GUESS;
+
+extern struct user *proc0paddr;
+
+int bcd2int __P((unsigned int));
+
+/*
+ * Called from locore.S during boot,
+ * this is the first C code that's run.
+ */
+
+void
+m187_bootstrap(void)
+{
+ extern char version[];
+ extern char *edata, *end;
+ extern int cold;
+ extern int kernelstart;
+ extern vm_offset_t size_memory(void);
+ struct bugbrdid brdid;
+
+ cold = 1; /* we are still booting */
+
+ bugbrdid(&brdid);
+ machineid = brdid.brdno;
+
+ vm_set_page_size();
+
+#if 0
+ esym = kflags.esym;
+ boothowto = kflags.bflags;
+ bootdev = kflags.bdev;
+#endif /* 0 */
+
+#if 0
+ end_loaded = kflags.end_load;
+ if (esym != NULL) {
+ end = (char *)((int)(kflags.symtab));
+ } else {
+ first_addr = (vm_offset_t)&end;
+ }
+#endif
+
+ first_addr = m88k_round_page(first_addr);
+
+ if (!no_symbols)
+ boothowto |= RB_KDB;
+
+ printf("about to probe\n");
+#if 1
+ last_addr = size_memory();
+#else
+ last_addr = (vm_offset_t)0x01000000;
+ physmem = btoc(last_addr);
+#endif
+
+ printf("probing done\n");
+ cmmu_init();
+
+ avail_start = first_addr;
+ avail_end = last_addr;
+ printf("%s",version);
+ printf("M187 boot: memory from 0x%x to 0x%x\n", avail_start, avail_end);
+
+ /*
+ * Steal one page at the top of physical memory for msgbuf
+ */
+
+ avail_end -= PAGE_SIZE;
+
+ pmap_bootstrap((vm_offset_t)&kernelstart - GOOFYLDOFFSET /* loadpt */,
+ &avail_start, &avail_end, &virtual_avail,
+ &virtual_end);
+ printf("returned from pmap_bootstrap\n");
+
+ /*
+ * Must initialize p_addr before autoconfig or
+ * the fault handler will get a NULL reference.
+ */
+ proc0.p_addr = proc0paddr;
+ curproc = &proc0;
+ curpcb = &proc0paddr->u_pcb;
+
+ /* Initialize cached PTEs for u-area mapping. */
+ save_u_area(&proc0, proc0paddr);
+
+ /*
+ * Map proc0's u-area at the standard address (UADDR).
+ */
+ load_u_area(&proc0);
+
+ /* Initialize the "u-area" pages. */
+ bzero((caddr_t)UADDR, UPAGES*NBPG);
+ printf("returning from init\n");
+}
+
+#ifdef notneeded
+ipow(int base, int i)
+{
+ int cnt = 1;
+ while (i--) {
+ cnt *= base;
+ }
+ return cnt;
+}
+
+int
+bcd2int(unsigned int i)
+{
+ unsigned val = 0;
+ int cnt = 0;
+ while (i) {
+ val += (i&0xf) * ipow(10,cnt);
+ cnt++;
+ i >>= 4;
+ }
+ return val;
+}
+#endif /* notneeded */
diff --git a/sys/arch/mvme88k/mvme88k/misc.s b/sys/arch/mvme88k/mvme88k/misc.s
new file mode 100644
index 00000000000..dea8fab94e5
--- /dev/null
+++ b/sys/arch/mvme88k/mvme88k/misc.s
@@ -0,0 +1,67 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * 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 Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ *
+ * HISTORY
+ * $Log: misc.s,v $
+ * Revision 1.1 1995/10/18 12:32:29 deraadt
+ * moved from m88k directory
+ *
+ * Revision 1.1.1.1 1995/10/18 10:54:27 deraadt
+ * initial 88k import; code by nivas and based on mach luna88k
+ *
+ * Revision 2.3 93/01/26 18:01:25 danner
+ * Conditionalied "#define ASSEMBLER".
+ * [93/01/25 jfriedl]
+ *
+ * Revision 2.2 92/08/03 17:52:14 jfriedl
+ * created [danner]
+ *
+ */
+
+#ifndef ASSEMBLER
+ #define ASSEMBLER
+#endif
+
+#include <m88k/asm.h>
+
+LABEL(_ff1)
+ jmp.n r1
+ ff1 r2, r2
+
+/*
+ * invalidate_pte(pte)
+ *
+ * This function will invalidate specified pte indivisibly
+ * to avoid the write-back of used-bit and/or modify-bit into
+ * that pte. It also returns the pte found in the table.
+ */
+LABEL(_invalidate_pte)
+ or r3,r0,r0
+ xmem r3,r2,0
+ tb1 0,r0,0
+ jmp.n r1
+ or r2,r3,r0