summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 12:31:48 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 12:31:48 +0000
commit91ed62167d774d2d4540b530093d0c45e835ac28 (patch)
treee0b97ce0fd2cab9568849ca5557e0ed699767e5a
parent7cc4cb13823c91c24d2025c78ac62997d1f5ca1b (diff)
moved to mvme88k directory
-rw-r--r--sys/arch/mvme88k/m88k/TODO4
-rw-r--r--sys/arch/mvme88k/m88k/autoconf.c204
-rw-r--r--sys/arch/mvme88k/m88k/clock.c483
-rw-r--r--sys/arch/mvme88k/m88k/cmmu.c1199
-rw-r--r--sys/arch/mvme88k/m88k/conf.c348
-rw-r--r--sys/arch/mvme88k/m88k/continuation.s238
-rw-r--r--sys/arch/mvme88k/m88k/eh.S1749
-rw-r--r--sys/arch/mvme88k/m88k/exception_return.s255
-rw-r--r--sys/arch/mvme88k/m88k/genassym.c151
-rw-r--r--sys/arch/mvme88k/m88k/locore.S496
-rw-r--r--sys/arch/mvme88k/m88k/locore2.c99
-rw-r--r--sys/arch/mvme88k/m88k/locore_asm_routines.S1668
-rw-r--r--sys/arch/mvme88k/m88k/locore_c_routines.c391
-rw-r--r--sys/arch/mvme88k/m88k/m1x7_init.c205
-rw-r--r--sys/arch/mvme88k/m88k/m88100_fp.S2463
-rw-r--r--sys/arch/mvme88k/m88k/machdep.c1360
-rw-r--r--sys/arch/mvme88k/m88k/misc.s64
-rw-r--r--sys/arch/mvme88k/m88k/pmap.c5538
-rw-r--r--sys/arch/mvme88k/m88k/process.S270
-rw-r--r--sys/arch/mvme88k/m88k/process_machdep.c155
-rw-r--r--sys/arch/mvme88k/m88k/swapgeneric.c237
-rw-r--r--sys/arch/mvme88k/m88k/syscall.stub29
-rw-r--r--sys/arch/mvme88k/m88k/timerreg.h8
-rw-r--r--sys/arch/mvme88k/m88k/trap.c608
-rw-r--r--sys/arch/mvme88k/m88k/vm_machdep.c289
25 files changed, 0 insertions, 18511 deletions
diff --git a/sys/arch/mvme88k/m88k/TODO b/sys/arch/mvme88k/m88k/TODO
deleted file mode 100644
index a6151ebd11e..00000000000
--- a/sys/arch/mvme88k/m88k/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-1. It appears that trap() assumes instruction access or data access
- faults can only be caused by page faults. Could do better by
- checking PFSR in the CMMU and handling parity errors, page faults,
- segmentation faults and protection faults appropriately.
diff --git a/sys/arch/mvme88k/m88k/autoconf.c b/sys/arch/mvme88k/m88k/autoconf.c
deleted file mode 100644
index cbac9fe7ad4..00000000000
--- a/sys/arch/mvme88k/m88k/autoconf.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 1994 Christian E. Hopps
- * 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 Christian E. Hopps.
- * 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.
- *
- * $Id: autoconf.c,v 1.1 1995/10/18 10:54:25 deraadt Exp $
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/reboot.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/disklabel.h>
-#include <machine/cpu.h>
-
-void configure __P((void));
-void setroot __P((void));
-void swapconf __P((void));
-
-int realconfig=0;
-int cold; /* 1 if still booting */
-#include <sys/kernel.h>
-/*
- * called at boot time, configure all devices on system
- */
-void
-configure()
-{
- /*
- * this is the real thing baby (i.e. not console init)
- */
- realconfig = 1;
-
- if (config_rootfound("mainbus", "mainbus") == 0)
- panic("no mainbus found");
-
-#ifdef GENERIC
- if ((boothowto & RB_ASKNAME) == 0)
- setroot();
- setconf();
-#else
- setroot();
-#endif
- swapconf();
- cold = 0;
-}
-
-/*ARGSUSED*/
-int
-simple_devprint(auxp, pnp)
- void *auxp;
- char *pnp;
-{
- return(QUIET);
-}
-
-int
-matchname(fp, sp)
- char *fp, *sp;
-{
- int len;
-
- len = strlen(fp);
- if (strlen(sp) != len)
- return(0);
- if (bcmp(fp, sp, len) == 0)
- return(1);
- return(0);
-}
-/*
- * this function needs to get enough configured to do a console
- * basically this means start attaching the grfxx's that support
- * the console. Kinda hacky but it works.
- */
-int
-config_console()
-{
- struct cfdata *cf;
-
- /*
- * we need mainbus' cfdata.
- */
- cf = config_rootsearch(NULL, "mainbus", "mainbus");
- if (cf == NULL)
- panic("no mainbus");
-}
-
-void
-swapconf()
-{
- struct swdevt *swp;
- u_int maj;
- int nb;
-
- for (swp = swdevt; swp->sw_dev > 0; swp++) {
- maj = major(swp->sw_dev);
-
- if (maj > nblkdev)
- break;
-
- if (bdevsw[maj].d_psize) {
- nb = bdevsw[maj].d_psize(swp->sw_dev);
- if (nb > 0 &&
- (swp->sw_nblks == 0 || swp->sw_nblks > nb))
- swp->sw_nblks = nb;
- else
- swp->sw_nblks = 0;
- }
- swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
- }
- if (dumplo == 0 && dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize)
- /*dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;*/
- dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
- ctob(physmem)/DEV_BSIZE;
- if (dumplo < 0)
- dumplo = 0;
-
-}
-
-#define DOSWAP /* change swdevt and dumpdev */
-u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
-
-static char devname[][2] = {
- 0,0,
- 0,0,
- 0,0,
- 0,0,
- 's','d', /* 4 = sd -- new SCSI system */
-};
-
-void
-setroot()
-{
- int majdev, mindev, unit, part, adaptor;
- dev_t temp, orootdev;
- struct swdevt *swp;
-
- printf("setroot boothowto %x bootdev %x\n", boothowto, bootdev);
- if (boothowto & RB_DFLTROOT ||
- (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
- return;
- majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
- if (majdev > sizeof(devname) / sizeof(devname[0]))
- return;
- adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
- part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
- unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
- orootdev = rootdev;
- rootdev = MAKEDISKDEV(majdev, unit, part);
- /*
- * If the original rootdev is the same as the one
- * just calculated, don't need to adjust the swap configuration.
- */
- if (rootdev == orootdev)
- return;
- printf("changing root device to %c%c%d%c\n",
- devname[majdev][0], devname[majdev][1],
- unit, part + 'a');
-#ifdef DOSWAP
- mindev = DISKUNIT(rootdev);
- for (swp = swdevt; swp->sw_dev; swp++) {
- printf("DOSWAP swap %x dev %x\n", swp, swp->sw_dev);
- if (majdev == major(swp->sw_dev) &&
- mindev == DISKUNIT(swp->sw_dev)) {
- temp = swdevt[0].sw_dev;
- swdevt[0].sw_dev = swp->sw_dev;
- swp->sw_dev = temp;
- break;
- }
- }
- if (swp->sw_dev == 0)
- return;
- /*
- * If dumpdev was the same as the old primary swap
- * device, move it to the new primary swap device.
- */
- if (temp == dumpdev)
- dumpdev = swdevt[0].sw_dev;
-#endif
-}
diff --git a/sys/arch/mvme88k/m88k/clock.c b/sys/arch/mvme88k/m88k/clock.c
deleted file mode 100644
index 50703114c09..00000000000
--- a/sys/arch/mvme88k/m88k/clock.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * 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 10:54:27 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/m88k/cmmu.c b/sys/arch/mvme88k/m88k/cmmu.c
deleted file mode 100644
index 2b76a62aeb2..00000000000
--- a/sys/arch/mvme88k/m88k/cmmu.c
+++ /dev/null
@@ -1,1199 +0,0 @@
-/*
- * 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
- */
-
-
-#define SNOOP_ENABLE
-#define SHADOW_BATC 0
-
-#ifndef NBPG
-#define NBPG 4096
-#endif /* NBPG */
-
-struct cmmu_regs
-{
- /* base + $000 */ volatile unsigned idr;
- /* base + $004 */ volatile unsigned scr;
- /* base + $008 */ volatile unsigned ssr;
- /* base + $00C */ volatile unsigned sar;
- /* */ unsigned padding1[0x3D];
- /* base + $104 */ volatile unsigned sctr;
- /* base + $108 */ volatile unsigned pfSTATUSr;
- /* base + $10C */ volatile unsigned pfADDRr;
- /* */ unsigned padding2[0x3C];
- /* base + $200 */ volatile unsigned sapr;
- /* base + $204 */ volatile unsigned uapr;
- /* */ unsigned padding3[0x7E];
- /* base + $400 */ volatile unsigned bwp[8];
- /* */ unsigned padding4[0xF8];
- /* base + $800 */ volatile unsigned cdp[4];
- /* */ unsigned padding5[0x0C];
- /* base + $840 */ volatile unsigned ctp[4];
- /* */ unsigned padding6[0x0C];
- /* base + $880 */ volatile unsigned cssp;
-
- /* The rest for the 88204 */
- #define cssp0 cssp
- /* */ unsigned padding7[0x03];
- /* base + $890 */ volatile unsigned cssp1;
- /* */ unsigned padding8[0x03];
- /* base + $8A0 */ volatile unsigned cssp2;
- /* */ unsigned padding9[0x03];
- /* base + $8B0 */ volatile unsigned cssp3;
-
-
-
-
-
-
-};
-
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <machine/board.h>
-#include <machine/cpus.h>
-#if 0
-#include <vm/pmap.h>
-#endif
-
-
-static struct cmmu {
- struct cmmu_regs *cmmu_regs; /* CMMU "base" area */
- unsigned char cmmu_cpu; /* cpu number it is attached to */
- unsigned char which; /* either INST_CMMU || DATA_CMMU */
- unsigned char cmmu_alive;
- #define CMMU_DEAD 0 /* This cmmu not there */
- #define CMMU_AVAILABLE 1 /* It's there, but which cpu's? */
- #define CMMU_MARRIED 2 /* Know which cpu it belongs to. */
- #if SHADOW_BATC
- unsigned batc[8];
- #endif
- unsigned char pad;
-} cmmu[MAX_CMMUS] = {
- {(void *)CMMU_I, 0, 0, 0, 0},
- {(void *)CMMU_D, 0, 1, 0, 0},
-};
-
-#include <machine/m882xx.h>
-/*
- * We rely upon and use INST_CMMU == 0 and DATA_CMMU == 1
- */
-#if INST_CMMU != 0 || DATA_CMMU != 1
- error("ack gag barf!");
-#endif
-struct cpu_cmmu {
- struct cmmu *pair[2];
-} cpu_cmmu[1];
-
-/*
- * CMMU(cpu,data) Is the cmmu struct for the named cpu's indicated cmmu.
- * REGS(cpu,data) is the actual register structure.
- */
-#define CMMU(cpu, data) cpu_cmmu[(cpu)].pair[(data)?DATA_CMMU:INST_CMMU]
-#define REGS(cpu, data) (*CMMU(cpu, data)->cmmu_regs)
-
-unsigned cache_policy = 0;
-
-#ifdef CMMU_DEBUG
-void show_apr(unsigned value)
-{
- union apr_template apr_template;
- apr_template.bits = value;
- _printf("table @ 0x%x000", apr_template.field.st_base);
- if (apr_template.field.wt) printf(", writethrough");
- if (apr_template.field.g) printf(", global");
- if (apr_template.field.ci) printf(", cache inhibit");
- if (apr_template.field.te) printf(", valid");
- else printf(", not valid");
- printf("]\n");
-}
-
-void show_sctr(unsigned value)
-{
- union {
- unsigned bits;
- struct {
- unsigned :16,
- pe: 1,
- se: 1,
- pr: 1,
- :13;
- } fields;
- } sctr;
- sctr.bits = value;
- printf("%spe, %sse %spr]\n",
- sctr.fields.pe ? "" : "!",
- sctr.fields.se ? "" : "!",
- sctr.fields.pr ? "" : "!");
-}
-#endif
-
-/*
- * CMMU initialization routine
- */
-void cmmu_init(void)
-{
- unsigned tmp, cmmu_num;
- union cpupid id;
- int cpu;
-
- cpu_cmmu[0].pair[INST_CMMU] = cpu_cmmu[0].pair[DATA_CMMU] = 0;
-
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++) {
- if (!wprobe((vm_offset_t)cmmu[cmmu_num].cmmu_regs, -1)) {
- id.cpupid = cmmu[cmmu_num].cmmu_regs->idr;
- if (id.m88200.type != M88200 && id.m88200.type != M88204)
- continue;
- cmmu[cmmu_num].cmmu_alive = CMMU_AVAILABLE;
-
- cpu_cmmu[cmmu[cmmu_num].cmmu_cpu].pair[cmmu[cmmu_num].which] =
- &cmmu[cmmu_num];
-
- /*
- * Reset cache data....
- * as per M88200 Manual (2nd Ed.) section 3.11.
- */
- for (tmp = 0; tmp < 255; tmp++) {
- cmmu[cmmu_num].cmmu_regs->sar = tmp << 4;
- cmmu[cmmu_num].cmmu_regs->cssp = 0x3f0ff000;
- }
-
- /* 88204 has additional cache to clear */
- if(id.m88200.type == M88204)
- {
- for (tmp = 0; tmp < 255; tmp++) {
- cmmu[cmmu_num].cmmu_regs->sar = tmp<<4;
- cmmu[cmmu_num].cmmu_regs->cssp1 = 0x3f0ff000;
- }
- for (tmp = 0; tmp < 255; tmp++) {
- cmmu[cmmu_num].cmmu_regs->sar = tmp<<4;
- cmmu[cmmu_num].cmmu_regs->cssp2 = 0x3f0ff000;
- }
- for (tmp = 0; tmp < 255; tmp++) {
- cmmu[cmmu_num].cmmu_regs->sar = tmp<<4;
- cmmu[cmmu_num].cmmu_regs->cssp3 = 0x3f0ff000;
- }
- }
-
- /*
- * Set the SCTR, SAPR, and UAPR to some known state
- * (I don't trust the reset to do it).
- */
- tmp =
- ! CMMU_SCTR_PE | /* not parity enable */
- ! CMMU_SCTR_SE | /* not snoop enable */
- ! CMMU_SCTR_PR ; /* not priority arbitration */
- cmmu[cmmu_num].cmmu_regs->sctr = tmp;
-
- tmp =
- (0x00000 << 12) | /* segment table base address */
- AREA_D_WT | /* write through */
- AREA_D_G | /* global */
- AREA_D_CI | /* cache inhibit */
- ! AREA_D_TE ; /* not translation enable */
- cmmu[cmmu_num].cmmu_regs->sapr =
- cmmu[cmmu_num].cmmu_regs->uapr = tmp;
-
-
-#if SHADOW_BATC
- cmmu[cmmu_num].batc[0] =
- cmmu[cmmu_num].batc[1] =
- cmmu[cmmu_num].batc[2] =
- cmmu[cmmu_num].batc[3] =
- cmmu[cmmu_num].batc[4] =
- cmmu[cmmu_num].batc[5] =
- cmmu[cmmu_num].batc[6] =
- cmmu[cmmu_num].batc[7] = 0;
-#endif
- cmmu[cmmu_num].cmmu_regs->bwp[0] =
- cmmu[cmmu_num].cmmu_regs->bwp[1] =
- cmmu[cmmu_num].cmmu_regs->bwp[2] =
- cmmu[cmmu_num].cmmu_regs->bwp[3] =
- cmmu[cmmu_num].cmmu_regs->bwp[4] =
- cmmu[cmmu_num].cmmu_regs->bwp[5] =
- cmmu[cmmu_num].cmmu_regs->bwp[6] =
- cmmu[cmmu_num].cmmu_regs->bwp[7] = 0;
- cmmu[cmmu_num].cmmu_regs->scr = CMMU_FLUSH_CACHE_INV_ALL;
- cmmu[cmmu_num].cmmu_regs->scr = CMMU_FLUSH_SUPER_ALL;
- cmmu[cmmu_num].cmmu_regs->scr = CMMU_FLUSH_USER_ALL;
- }
- }
-
- /*
- * Now that we know which CMMUs are there, let's report on which
- * CPU/CMMU sets seem complete (hopefully all)
- */
- for (cpu = 0; cpu < MAX_CPUS; cpu++)
- {
- if (cpu_cmmu[cpu].pair[INST_CMMU] && cpu_cmmu[cpu].pair[DATA_CMMU])
- {
- if(id.m88200.type == M88204)
- printf("CPU%d is attached with MC88204 CMMU\n", cpu);
- else
- printf("CPU%d is attached with MC88200 CMMU\n", cpu);
-
- }
- else if (cpu_cmmu[cpu].pair[INST_CMMU])
- {
- printf("CPU%d data CMMU is not working.\n", cpu);
- panic("cmmu-data");
- }
- else if (cpu_cmmu[cpu].pair[DATA_CMMU])
- {
- printf("CPU%d instruction CMMU is not working.\n", cpu);
- panic("cmmu");
- }
- else
- {
- }
- }
-
- /*
- * Enable snooping...
- */
- for (cpu = 0; cpu < MAX_CPUS; cpu++)
- {
- /*
- * Enable snooping.
- * We enable it for instruction cmmus as well so that we can have
- * breakpoints, etc, and modify code.
- */
- tmp =
- ! CMMU_SCTR_PE | /* not parity enable */
- CMMU_SCTR_SE | /* snoop enable */
- ! CMMU_SCTR_PR ; /* not priority arbitration */
- REGS(cpu, DATA_CMMU).sctr = tmp;
- REGS(cpu, INST_CMMU).sctr = tmp;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_SUPER_ALL;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_SUPER_ALL;
- }
-
- /*
- * Turn on some cache.
- */
- for (cpu = 0; cpu < MAX_CPUS; cpu++)
- {
- /*
- * Enable some caching for the instruction stream.
- * Can't cache data yet 'cause device addresses can never
- * be cached, and we don't have those no-caching zones
- * set up yet....
- */
- tmp =
- (0x00000 << 12) | /* segment table base address */
- AREA_D_WT | /* write through */
- AREA_D_G | /* global */
- AREA_D_CI | /* cache inhibit */
- ! AREA_D_TE ; /* not translation enable */
- REGS(cpu, INST_CMMU).sapr = tmp;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_SUPER_ALL;
- }
-}
-
-/*
- * Just before poweroff or reset....
- */
-void cmmu_shutdown_now(void)
-{
-#if 0 /* was trying to fix a reboot problem... doesn't seem to help */
- unsigned tmp;
- unsigned cmmu_num;
-
- /*
- * Now set some state as we like...
- */
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++)
- {
- tmp =
- ! CMMU_SCTR_PE | /* parity enable */
- ! CMMU_SCTR_SE | /* snoop enable */
- ! CMMU_SCTR_PR ; /* priority arbitration */
- cmmu[cmmu_num].cmmu_regs->sctr = tmp;
-
-
- tmp =
- (0x00000 << 12) | /* segment table base address */
- ! AREA_D_WT | /* write through */
- ! AREA_D_G | /* global */
- AREA_D_CI | /* cache inhibit */
- ! AREA_D_TE ; /* translation enable */
- cmmu[cmmu_num].cmmu_regs->sapr = tmp;
- cmmu[cmmu_num].cmmu_regs->uapr = tmp;
- }
-#endif
-}
-
-
-/*
- * enable parity
- */
-void cmmu_parity_enable(void)
-{
-#ifdef PARITY_ENABLE
- register int cmmu_num;
-
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++) {
- if (cmmu[cmmu_num].cmmu_alive != CMMU_DEAD) {
- cmmu[cmmu_num].cmmu_regs->sctr |= CMMU_SCTR_PE;
- }
- }
-#endif PARITY_ENABLE
-}
-
-/*
- * Find out the CPU number from accessing CMMU
- * Better be at splhigh, or even better, with interrupts
- * disabled.
- */
-unsigned cmmu_cpu_number(void)
-{
- register unsigned cmmu_no;
- int i;
-
- for (i=0; i < 10; i++)
- {
- /* clear CMMU p-bus status registers */
- for (cmmu_no = 0; cmmu_no < MAX_CMMUS; cmmu_no++)
- {
- if (cmmu[cmmu_no].cmmu_alive == CMMU_AVAILABLE &&
- cmmu[cmmu_no].which == DATA_CMMU)
- cmmu[cmmu_no].cmmu_regs->pfSTATUSr = 0;
- }
-
- /* access faulting address */
- badwordaddr((void *)ILLADDRESS);
-
- /* check which CMMU reporting the fault */
- for (cmmu_no = 0; cmmu_no < MAX_CMMUS; cmmu_no++)
- {
- if (cmmu[cmmu_no].cmmu_alive == CMMU_AVAILABLE &&
- cmmu[cmmu_no].which == DATA_CMMU &&
- cmmu[cmmu_no].cmmu_regs->pfSTATUSr & 0x70000)
- {
- if (cmmu[cmmu_no].cmmu_regs->pfSTATUSr & 0x70000)
- {
- cmmu[cmmu_no].cmmu_regs->pfSTATUSr = 0; /* to be clean */
- cmmu[cmmu_no].cmmu_alive = CMMU_MARRIED;
- return cmmu[cmmu_no].cmmu_cpu;
- }
- }
- }
- }
-printf("at cmmu.c line %d.\n", __LINE__);
-
- panic("could not determine my cpu number");
- return 0; /* to make compiler happy */
-}
-
-/**
- ** Funcitons that actually modify CMMU registers.
- **/
-
-#if !DDB
-static
-#endif
-void cmmu_remote_set(unsigned cpu, unsigned r, unsigned data, unsigned x)
-{
- *(volatile unsigned *)(r + (char*)&REGS(cpu,data)) = x;
-}
-
-/*
- * cmmu_cpu_lock should be held when called if read
- * the CMMU_SCR or CMMU_SAR.
-**/
-#if !DDB
-static
-#endif
-unsigned cmmu_remote_get(unsigned cpu, unsigned r, unsigned data)
-{
- return *(volatile unsigned *)(r + (char*)&REGS(cpu,data));
-}
-
-/* Needs no locking - read only registers */
-unsigned cmmu_get_idr(unsigned data)
-{
- return REGS(0,data).idr;
-}
-
-void cmmu_set_sapr(unsigned ap)
-{
- int cpu = 0;
- if (cache_policy & CACHE_INH)
- ap |= AREA_D_CI;
-
- REGS(cpu, INST_CMMU).sapr = ap;
- REGS(cpu, DATA_CMMU).sapr = ap;
-}
-
-void cmmu_remote_set_sapr(unsigned cpu, unsigned ap)
-{
- if (cache_policy & CACHE_INH)
- ap |= AREA_D_CI;
- REGS(cpu, INST_CMMU).sapr = ap;
- REGS(cpu, DATA_CMMU).sapr = ap;
-}
-
-void cmmu_set_uapr(unsigned ap)
-{
- int cpu = 0;
- /* this functionality also mimiced in cmmu_pmap_activate() */
- REGS(cpu, INST_CMMU).uapr = ap;
- REGS(cpu, DATA_CMMU).uapr = ap;
-}
-
-/*
- * Set batc entry number entry_no to value in
- * the data or instruction cache depending on data.
- *
- * Except for the cmmu_init, this function, cmmu_set_pair_batc_entry,
- * and cmmu_pmap_activate are the only functions which may set the
- * batc values.
- */
-void cmmu_set_batc_entry(
- unsigned cpu,
- unsigned entry_no,
- unsigned data, /* 1 = data, 0 = instruction */
- unsigned value) /* the value to stuff into the batc */
-{
-
- REGS(cpu,data).bwp[entry_no] = value;
- #if SHADOW_BATC
- CMMU(cpu,data)->batc[entry_no] = value;
- #endif
-#if 0 /* was for debugging piece (peace?) of mind */
- REGS(cpu,data).scr = CMMU_FLUSH_SUPER_ALL;
- REGS(cpu,data).scr = CMMU_FLUSH_USER_ALL;
-#endif
-
-}
-
-/*
- * Set batc entry number entry_no to value in
- * the data and instruction cache for the named CPU.
- */
-void cmmu_set_pair_batc_entry(
- unsigned cpu,
- unsigned entry_no,
- unsigned value) /* the value to stuff into the batc */
-{
-
- REGS(cpu,DATA_CMMU).bwp[entry_no] = value;
- #if SHADOW_BATC
- CMMU(cpu,DATA_CMMU)->batc[entry_no] = value;
- #endif
- REGS(cpu,INST_CMMU).bwp[entry_no] = value;
- #if SHADOW_BATC
- CMMU(cpu,INST_CMMU)->batc[entry_no] = value;
- #endif
-
-#if 0 /* was for debugging piece (peace?) of mind */
- REGS(cpu,INST_CMMU).scr = CMMU_FLUSH_SUPER_ALL;
- REGS(cpu,INST_CMMU).scr = CMMU_FLUSH_USER_ALL;
- REGS(cpu,DATA_CMMU).scr = CMMU_FLUSH_SUPER_ALL;
- REGS(cpu,DATA_CMMU).scr = CMMU_FLUSH_USER_ALL;
-#endif
-
-}
-
-/**
- ** Functions that invalidate TLB entries.
- **/
-
-/*
- * flush any tlb
- * Some functionality mimiced in cmmu_pmap_activate.
- */
-void cmmu_flush_remote_tlb(
- unsigned cpu,
- unsigned kernel,
- vm_offset_t vaddr,
- int size)
-{
- register s = splhigh();
-
- if ((unsigned)size > M88K_PGBYTES)
- {
- REGS(cpu, INST_CMMU).scr =
- REGS(cpu, DATA_CMMU).scr =
- kernel ? CMMU_FLUSH_SUPER_ALL : CMMU_FLUSH_USER_ALL;
- }
- else /* a page or smaller */
- {
- REGS(cpu, INST_CMMU).sar = (unsigned)vaddr;
- REGS(cpu, DATA_CMMU).sar = (unsigned)vaddr;
-
- REGS(cpu, INST_CMMU).scr =
- REGS(cpu, DATA_CMMU).scr =
- kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE;
- }
- splx(s);
-}
-
-/*
- * flush my personal tlb
- */
-void cmmu_flush_tlb(unsigned kernel, vm_offset_t vaddr, int size)
-{
- cmmu_flush_remote_tlb(0, kernel, vaddr, size);
-}
-
-
-/*
- * New fast stuff for pmap_activate.
- * Does what a few calls used to do.
- * Only called from pmap.c's _pmap_activate().
- */
-void cmmu_pmap_activate(
- unsigned cpu,
- unsigned uapr,
- batc_template_t i_batc[BATC_MAX],
- batc_template_t d_batc[BATC_MAX])
-{
- int entry_no;
-
- /* the following is from cmmu_set_uapr */
- REGS(cpu, INST_CMMU).uapr = uapr;
- REGS(cpu, DATA_CMMU).uapr = uapr;
-
- for (entry_no = 0; entry_no < BATC_MAX; entry_no++) {
- REGS(cpu,INST_CMMU).bwp[entry_no] = i_batc[entry_no].bits;
- REGS(cpu,DATA_CMMU).bwp[entry_no] = d_batc[entry_no].bits;
- #if SHADOW_BATC
- CMMU(cpu,INST_CMMU)->batc[entry_no] = i_batc[entry_no].bits;
- CMMU(cpu,DATA_CMMU)->batc[entry_no] = d_batc[entry_no].bits;
- #endif
- }
-
- /*
- * Flush the user TLB.
- * IF THE KERNEL WILL EVER CARE ABOUT THE BATC ENTRIES,
- * THE SUPERVISOR TLBs SHOULB EE FLUSHED AS WELL.
- */
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_USER_ALL;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_USER_ALL;
-}
-
-/**
- ** Functions that invalidate caches.
- **
- ** Cache invalidates require physical addresses. Care must be exercised when
- ** using segment invalidates. This implies that the starting physical address
- ** plus the segment length should be invalidated. A typical mistake is to
- ** extract the first physical page of a segment from a virtual address, and
- ** then expecting to invalidate when the pages are not physically contiguous.
- **
- ** We don't push Instruction Caches prior to invalidate because they are not
- ** snooped and never modified (I guess it doesn't matter then which form
- ** of the command we use then).
- **/
-/*
- * flush both Instruction and Data caches
- */
-void cmmu_flush_remote_cache(int cpu, vm_offset_t physaddr, int size)
-{
- register s = splhigh();
-
-
- if (size < 0 || size > NBSG ) {
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_ALL;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_ALL;
- }
- else if (size <= 16) {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_LINE;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_LINE;
- }
- else if (size <= NBPG) {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_PAGE;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_PAGE;
- }
- else {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_SEGMENT;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_SEGMENT;
- }
-
-
- splx(s);
-}
-
-/*
- * flush both Instruction and Data caches
- */
-void cmmu_flush_cache(vm_offset_t physaddr, int size)
-{
- cmmu_flush_remote_cache(0, physaddr, size);
-}
-
-/*
- * flush Instruction caches
- */
-void cmmu_flush_remote_inst_cache(int cpu, vm_offset_t physaddr, int size)
-{
- register s = splhigh();
-
-
- if (size < 0 || size > NBSG ) {
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_ALL;
- }
- else if (size <= 16) {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_LINE;
- }
- else if (size <= NBPG) {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_PAGE;
- }
- else {
- REGS(cpu, INST_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, INST_CMMU).scr = CMMU_FLUSH_CACHE_CBI_SEGMENT;
- }
-
-
- splx(s);
-}
-
-/*
- * flush Instruction caches
- */
-void cmmu_flush_inst_cache(vm_offset_t physaddr, int size)
-{
- cmmu_flush_remote_inst_cache(0, physaddr, size);
-}
-
-void cmmu_flush_remote_data_cache(int cpu, vm_offset_t physaddr, int size)
-{
- register s = splhigh();
-
-
- if (size < 0 || size > NBSG ) {
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_ALL;
- }
- else if (size <= 16) {
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_LINE;
- }
- else if (size <= NBPG) {
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_PAGE;
- }
- else {
- REGS(cpu, DATA_CMMU).sar = (unsigned)physaddr;
- REGS(cpu, DATA_CMMU).scr = CMMU_FLUSH_CACHE_CBI_SEGMENT;
- }
-
-
- splx(s);
-}
-
-/*
- * flush data cache
- */
-void cmmu_flush_data_cache(vm_offset_t physaddr, int size)
-{
- cmmu_flush_remote_data_cache(0, physaddr, size);
-}
-
-
-#if 0
-#if DDB
-union ssr {
- unsigned bits;
- struct {
- unsigned :16,
- ce:1,
- be:1,
- :4,
- wt:1,
- sp:1,
- g:1,
- ci:1,
- :1,
- m:1,
- u:1,
- wp:1,
- bh:1,
- v:1;
- } field;
-};
-
-union cssp {
- unsigned bits;
- struct {
- unsigned : 2,
- l: 6,
- d3: 1,
- d2: 1,
- d1: 1,
- d0: 1,
- vv3: 2,
- vv2: 2,
- vv1: 2,
- vv0: 2,
- :12;
- } field;
-};
-
-union batcu {
- unsigned bits;
- struct { /* block address translation register */
- unsigned int
- lba:13, /* logical block address */
- pba:13, /* physical block address */
- s:1, /* supervisor */
- wt:4, /* write through */
- g:1, /* global */
- ci:1, /* cache inhibit */
- wp:1, /* write protect */
- v:1; /* valid */
- } field;
-};
-
-#define VV_EX_UNMOD 0
-#define VV_EX_MOD 1
-#define VV_SHARED_UNMOD 2
-#define VV_INVALID 3
-
-#define D(UNION, LINE) \
- ((LINE) == 3 ? (UNION).field.d3 : \
- ((LINE) == 2 ? (UNION).field.d2 : \
- ((LINE) == 1 ? (UNION).field.d1 : \
- ((LINE) == 0 ? (UNION).field.d0 : ~0))))
-#define VV(UNION, LINE) \
- ((LINE) == 3 ? (UNION).field.vv3 : \
- ((LINE) == 2 ? (UNION).field.vv2 : \
- ((LINE) == 1 ? (UNION).field.vv1 : \
- ((LINE) == 0 ? (UNION).field.vv0 : ~0))))
-
-
-/*
- * Show (for debugging) how the given CMMU translates the given ADDRESS.
- * If cmmu == -1, the data cmmu for the current cpu is used.
- */
-void cmmu_show_translation(
- unsigned address,
- unsigned supervisor_flag,
- unsigned verbose_flag,
- int cmmu_num)
-{
- /*
- * A virtual address is split into three fields. Two are used as
- * indicies into tables (segment and page), and one is an offset into
- * a page of memory.
- */
- union {
- unsigned bits;
- struct {
- unsigned segment_table_index:10,
- page_table_index:10,
- page_offset:12;
- } field;
- } virtual_address;
- unsigned value;
-
- if (verbose_flag)
- db_printf("-------------------------------------------\n");
-
-
- /****** ACCESS PROPER CMMU or THREAD ***********/
- if (thread != 0)
- {
- /* the following tidbit from _pmap_activate in m88k/pmap.c */
- register apr_template_t apr_data;
- supervisor_flag = 0; /* thread implies user */
-
- if (thread->task == 0) {
- db_printf("[thread %x has empty task pointer]\n", thread);
- return;
- } else if (thread->task->map == 0) {
- db_printf("[thread/task %x/%x has empty map pointer]\n",
- thread, thread->task);
- return;
- } else if (thread->task->map->pmap == 0) {
- db_printf("[thread/task/map %x/%x/%x has empty pmap pointer]\n",
- thread, thread->task, thread->task->map);
- return;
- }
- if (thread->task->map->pmap->lock.lock_data) {
- db_printf("[Warning: thread %x's task %x's map %x's "
- "pmap %x is locked]\n", thread, thread->task,
- thread->task->map, thread->task->map->pmap);
- }
- apr_data.bits = 0;
- apr_data.field.st_base = M88K_BTOP(thread->task->map->pmap->sdt_paddr);
- apr_data.field.wt = 0;
- apr_data.field.g = 1;
- apr_data.field.ci = 0;
- apr_data.field.te = 1;
- value = apr_data.bits;
- if (verbose_flag) {
- db_printf("[thread %x task %x map %x pmap %x UAPR is %x]\n",
- thread, thread->task, thread->task->map,
- thread->task->map->pmap, value);
- }
- } else {
- if (cmmu_num == -1)
- {
- if (cpu_cmmu[0].pair[DATA_CMMU] == 0)
- {
- db_printf("ack! can't figure my own data cmmu number.\n");
- return;
- }
- cmmu_num = cpu_cmmu[0].pair[DATA_CMMU] - cmmu;
- if (verbose_flag)
- db_printf("The data cmmu for cpu#%d is cmmu#%d.\n",
- 0, cmmu_num);
- }
- else if (cmmu_num < 0 || cmmu_num >= MAX_CMMUS)
- {
- db_printf("invalid cpu number [%d]... must be in range [0..%d]\n",
- cmmu_num, MAX_CMMUS - 1);
- return;
- }
-
- if (cmmu[cmmu_num].cmmu_alive == 0)
- {
- db_printf("warning: cmmu %d is not alive.\n", cmmu_num);
- #if 0
- return;
- #endif
- }
-
- if (!verbose_flag)
- {
- if (!(cmmu[cmmu_num].cmmu_regs->sctr & CMMU_SCTR_SE))
- db_printf("WARNING: snooping not enabled for CMMU#%d.\n",
- cmmu_num);
- }
- else
- {
- int i;
- for (i=0; i<MAX_CMMUS; i++)
- if ((i == cmmu_num || cmmu[i].cmmu_alive) &&
- (verbose_flag>1 || !(cmmu[i].cmmu_regs->sctr&CMMU_SCTR_SE)))
- {
- db_printf("CMMU#%d (cpu %d %s) snooping %s\n", i,
- cmmu[i].cmmu_cpu, cmmu[i].which ? "data" : "inst",
- (cmmu[i].cmmu_regs->sctr & CMMU_SCTR_SE) ? "on":"OFF");
- }
- }
-
- if (supervisor_flag)
- value = cmmu[cmmu_num].cmmu_regs->sapr;
- else
- value = cmmu[cmmu_num].cmmu_regs->uapr;
-
- }
-
- /******* LOOK AT THE BATC ** (if not a thread) **************/
- #if SHADOW_BATC
- if (thread == 0)
- {
- int i;
- union batcu batc;
- for (i = 0; i < 8; i++) {
- batc.bits = cmmu[cmmu_num].batc[i];
- if (batc.field.v == 0) {
- if (verbose_flag>1)
- db_printf("cmmu #%d batc[%d] invalid.\n", cmmu_num, i);
- } else {
- db_printf("cmmu#%d batc[%d] v%08x p%08x", cmmu_num, i,
- batc.field.lba << 18, batc.field.pba);
- if (batc.field.s) db_printf(", supervisor");
- if (batc.field.wt) db_printf(", wt.th");
- if (batc.field.g) db_printf(", global");
- if (batc.field.ci) db_printf(", cache inhibit");
- if (batc.field.wp) db_printf(", write protect");
- }
- }
- }
- #endif
-
- /******* SEE WHAT A PROBE SAYS (if not a thread) ***********/
- if (thread == 0)
- {
- union ssr ssr;
- struct cmmu_regs *cmmu_regs = cmmu[cmmu_num].cmmu_regs;
- cmmu_regs->sar = address;
- cmmu_regs->scr = supervisor_flag ? CMMU_PROBE_SUPER : CMMU_PROBE_USER;
- ssr.bits = cmmu_regs->ssr;
- if (verbose_flag > 1)
- db_printf("probe of 0x%08x returns ssr=0x%08x\n",
- address, ssr.bits);
- if (ssr.field.v)
- db_printf("PROBE of 0x%08x returns phys=0x%x",
- address, cmmu_regs->sar);
- else
- db_printf("PROBE fault at 0x%x", cmmu_regs->pfADDRr);
- if (ssr.field.ce) db_printf(", copyback err");
- if (ssr.field.be) db_printf(", bus err");
- if (ssr.field.wt) db_printf(", writethrough");
- if (ssr.field.sp) db_printf(", sup prot");
- if (ssr.field.g) db_printf(", global");
- if (ssr.field.ci) db_printf(", cache inhibit");
- if (ssr.field.m) db_printf(", modified");
- if (ssr.field.u) db_printf(", used");
- if (ssr.field.wp) db_printf(", write prot");
- if (ssr.field.bh) db_printf(", BATC");
- db_printf(".\n");
- }
-
- /******* INTERPRET AREA DESCRIPTOR *********/
- {
- union apr_template apr_template;
- apr_template.bits = value;
- if (verbose_flag > 1) {
- if (thread == 0)
- db_printf("CMMU#%d", cmmu_num);
- else
- db_printf("THREAD %x", thread);
- db_printf(" %cAPR is 0x%08x\n",
- supervisor_flag ? 'S' : 'U', apr_template.bits);
- }
- if (thread == 0)
- db_printf("CMMU#%d", cmmu_num);
- else
- db_printf("THREAD %x", thread);
- db_printf(" %cAPR: SegTbl: 0x%x000p",
- supervisor_flag ? 'S' : 'U', apr_template.field.st_base);
- if (apr_template.field.wt) db_printf(", WTHRU");
- else db_printf(", !wthru");
- if (apr_template.field.g) db_printf(", GLOBAL");
- else db_printf(", !global");
- if (apr_template.field.ci) db_printf(", $INHIBIT");
- else db_printf(", $ok");
- if (apr_template.field.te) db_printf(", VALID");
- else db_printf(", !valid");
- db_printf(".\n");
-
- /* if not valid, done now */
- if (apr_template.field.te == 0) {
- db_printf("<would report an error, valid bit not set>\n");
- return;
- }
-
- value = apr_template.field.st_base << 12; /* now point to seg page */
- }
-
- /* translate value from physical to virtual */
- if (verbose_flag)
- db_printf("[%x physical is %x virtual]\n", value, value + VEQR_ADDR);
- value += VEQR_ADDR;
-
- virtual_address.bits = address;
-
- /****** ACCESS SEGMENT TABLE AND INTERPRET SEGMENT DESCRIPTOR *******/
- {
- union sdt_entry_template std_template;
- if (verbose_flag)
- db_printf("will follow to entry %d of page at 0x%x...\n",
- virtual_address.field.segment_table_index, value);
- value |= virtual_address.field.segment_table_index *
- sizeof(struct sdt_entry);
-
- if (badwordaddr(value)) {
- db_printf("ERROR: unable to access page at 0x%08x.\n", value);
- return;
- }
-
- std_template.bits = *(unsigned *)value;
- if (verbose_flag > 1)
- db_printf("SEG DESC @0x%x is 0x%08x\n", value, std_template.bits);
- db_printf("SEG DESC @0x%x: PgTbl: 0x%x000",
- value, std_template.sdt_desc.table_addr);
- if (std_template.sdt_desc.wt) db_printf(", WTHRU");
- else db_printf(", !wthru");
- if (std_template.sdt_desc.sup) db_printf(", S-PROT");
- else db_printf(", UserOk");
- if (std_template.sdt_desc.g) db_printf(", GLOBAL");
- else db_printf(", !global");
- if (std_template.sdt_desc.no_cache) db_printf(", $INHIBIT");
- else db_printf(", $ok");
- if (std_template.sdt_desc.prot) db_printf(", W-PROT");
- else db_printf(", WriteOk");
- if (std_template.sdt_desc.dtype) db_printf(", VALID");
- else db_printf(", !valid");
- db_printf(".\n");
-
- /* if not valid, done now */
- if (std_template.sdt_desc.dtype == 0) {
- db_printf("<would report an error, STD entry not valid>\n");
- return;
- }
-
- value = std_template.sdt_desc.table_addr << 12;
- }
-
- /* translate value from physical to virtual */
- if (verbose_flag)
- db_printf("[%x physical is %x virtual]\n", value, value + VEQR_ADDR);
- value += VEQR_ADDR;
-
- /******* PAGE TABLE *********/
- {
- union pte_template pte_template;
- if (verbose_flag)
- db_printf("will follow to entry %d of page at 0x%x...\n",
- virtual_address.field.page_table_index, value);
- value |= virtual_address.field.page_table_index *
- sizeof(struct pt_entry);
-
- if (badwordaddr(value)) {
- db_printf("error: unable to access page at 0x%08x.\n", value);
- return;
- }
-
- pte_template.bits = *(unsigned *)value;
- if (verbose_flag > 1)
- db_printf("PAGE DESC @0x%x is 0x%08x.\n", value, pte_template.bits);
- db_printf("PAGE DESC @0x%x: page @%x000",
- value, pte_template.pte.pfn);
- if (pte_template.pte.wired) db_printf(", WIRE");
- else db_printf(", !wire");
- if (pte_template.pte.wt) db_printf(", WTHRU");
- else db_printf(", !wthru");
- if (pte_template.pte.sup) db_printf(", S-PROT");
- else db_printf(", UserOk");
- if (pte_template.pte.g) db_printf(", GLOBAL");
- else db_printf(", !global");
- if (pte_template.pte.ci) db_printf(", $INHIBIT");
- else db_printf(", $ok");
- if (pte_template.pte.modified) db_printf(", MOD");
- else db_printf(", !mod");
- if (pte_template.pte.pg_used) db_printf(", USED");
- else db_printf(", !used");
- if (pte_template.pte.prot) db_printf(", W-PROT");
- else db_printf(", WriteOk");
- if (pte_template.pte.dtype) db_printf(", VALID");
- else db_printf(", !valid");
- db_printf(".\n");
-
- /* if not valid, done now */
- if (pte_template.pte.dtype == 0) {
- db_printf("<would report an error, PTE entry not valid>\n");
- return;
- }
-
- value = pte_template.pte.pfn << 12;
- if (verbose_flag)
- db_printf("will follow to byte %d of page at 0x%x...\n",
- virtual_address.field.page_offset, value);
- value |= virtual_address.field.page_offset;
-
- if (badwordaddr(value)) {
- db_printf("error: unable to access page at 0x%08x.\n", value);
- return;
- }
- }
-
- /* translate value from physical to virtual */
- if (verbose_flag)
- db_printf("[%x physical is %x virtual]\n", value, value + VEQR_ADDR);
- value += VEQR_ADDR;
-
- db_printf("WORD at 0x%x is 0x%08x.\n", value, *(unsigned *)value);
-}
-
-
-void cmmu_cache_state(unsigned addr, unsigned supervisor_flag)
-{
- static char *vv_name[4] =
- {"exclu-unmod", "exclu-mod", "shared-unmod", "invalid"};
- int cmmu_num;
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++)
- {
- union ssr ssr;
- union cssp cssp;
- struct cmmu_regs *R;
- unsigned tag, line;
- if (!cmmu[cmmu_num].cmmu_alive)
- continue;
- R = cmmu[cmmu_num].cmmu_regs;
- db_printf("cmmu #%d %s cmmu for cpu %d.\n", cmmu_num,
- cmmu[cmmu_num].which ? "data" : "inst",
- cmmu[cmmu_num].cmmu_cpu);
- R->sar = addr;
- R->scr = supervisor_flag ? CMMU_PROBE_SUPER : CMMU_PROBE_USER;
-
- ssr.bits = R->ssr;
- if (!ssr.field.v) {
- db_printf("PROBE of 0x%08x faults.\n",addr);
- continue;
- }
- db_printf("PROBE of 0x%08x returns phys=0x%x", addr, R->sar);
-
- tag = R->sar & ~0xfff;
- cssp.bits = R->cssp;
-
- /* check to see if any of the tags for the set match the address */
- for (line = 0; line < 4; line++)
- {
- if (VV(cssp, line) == VV_INVALID)
- {
- db_printf("line %d invalid.\n", line);
- continue; /* line is invalid */
- }
- if (D(cssp, line))
- {
- db_printf("line %d disabled.\n", line);
- continue; /* line is disabled */
- }
-
- if ((R->ctp[line] & ~0xfff) != tag)
- {
- db_printf("line %d address tag is %x.\n", line,
- (R->ctp[line] & ~0xfff));
- continue;
- }
- db_printf("found in line %d as %08x (%s).\n",
- line, R->cdp[line], vv_name[VV(cssp, line)]);
- }
- }
-}
-
-void show_cmmu_info(unsigned addr)
-{
- int cmmu_num;
- cmmu_cache_state(addr, 1);
-
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++)
- if (cmmu[cmmu_num].cmmu_alive) {
- db_printf("cmmu #%d %s cmmu for cpu %d: ", cmmu_num,
- cmmu[cmmu_num].which ? "data" : "inst",
- cmmu[cmmu_num].cmmu_cpu);
- cmmu_show_translation(addr, 1, 0, cmmu_num);
- }
-}
-#endif /* end if DDB */
-#endif /* 0 */
diff --git a/sys/arch/mvme88k/m88k/conf.c b/sys/arch/mvme88k/m88k/conf.c
deleted file mode 100644
index ac48d0a62e6..00000000000
--- a/sys/arch/mvme88k/m88k/conf.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* $NetBSD: conf.c,v 1.28 1995/04/19 22:37:27 mycroft Exp $ */
-
-/*-
- * Copyright (c) 1991 The 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.
- *
- * @(#)conf.c 7.9 (Berkeley) 5/28/91
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/conf.h>
-#include <sys/vnode.h>
-
-int ttselect __P((dev_t, int, struct proc *));
-
-bdev_decl(sw);
-#include "st.h"
-bdev_decl(st);
-#include "sd.h"
-bdev_decl(sd);
-#include "cd.h"
-bdev_decl(cd);
-
-#if notyet
-#include "ch.h"
-bdev_decl(ch);
-#include "xd.h"
-bdev_decl(xd);
-#endif /* notyet */
-
-#include "vnd.h"
-bdev_decl(vnd);
-
-#ifdef LKM
-int lkmenodev();
-#else
-#define lkmenodev enodev
-#endif
-
-struct bdevsw bdevsw[] =
-{
- bdev_notdef(), /* 0 */
- bdev_notdef(), /* 1 */
- bdev_notdef(), /* 2 */
- bdev_swap_init(1,sw), /* 3: swap pseudo-device */
- bdev_disk_init(NSD,sd), /* 4: SCSI disk */
- bdev_tape_init(NST,st), /* 5: SCSI tape */
- bdev_disk_init(NCD,cd), /* 6: SCSI CD-ROM */
- bdev_notdef(), /* 7 */
- bdev_disk_init(NVND,vnd), /* 8: vnode disk driver */
- bdev_notdef(), /* 9 */
-#if notyet
- bdev_disk_init(NXD,xd), /* 10: XD disk */
-#endif /* notyet */
- bdev_notdef(), /* 11 */
- bdev_notdef(), /* 12 */
- bdev_lkm_dummy(), /* 13 */
- bdev_lkm_dummy(), /* 14 */
- bdev_lkm_dummy(), /* 15 */
- bdev_lkm_dummy(), /* 16 */
- bdev_lkm_dummy(), /* 17 */
- bdev_lkm_dummy(), /* 18 */
-};
-int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
-
-cdev_decl(cn);
-cdev_decl(ctty);
-#define mmread mmrw
-#define mmwrite mmrw
-#if notyet
-cdev_decl(mm);
-#endif /* notyet */
-cdev_decl(sw);
-
-#if notyet
-#include "sram.h"
-cdev_decl(sram);
-
-#include "vmel.h"
-cdev_decl(vmel);
-
-#include "vmes.h"
-cdev_decl(vmes);
-
-#include "nvram.h"
-cdev_decl(nvram);
-
-#include "flash.h"
-cdev_decl(flash);
-#endif /* notyet */
-
-#include "pty.h"
-#define ptstty ptytty
-#define ptsioctl ptyioctl
-cdev_decl(pts);
-#define ptctty ptytty
-#define ptcioctl ptyioctl
-cdev_decl(ptc);
-cdev_decl(log);
-cdev_decl(fd);
-
-#if notyet
-#include "zs.h"
-cdev_decl(zs);
-#include "cl.h"
-cdev_decl(cl);
-#endif /* notyet */
-
-#include "bugtty.h"
-cdev_decl(bugtty);
-
-/* open, close, write, ioctl */
-#define cdev_lp_init(c,n) { \
- dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
- dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
- 0, seltrue, (dev_type_mmap((*))) enodev }
-
-/* open, close, ioctl, mmap, ioctl */
-#define cdev_mdev_init(c,n) { \
- dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
- dev_init(c,n,write), dev_init(c,n,ioctl), \
- (dev_type_stop((*))) enodev, 0, (dev_type_select((*))) enodev, \
- dev_init(c,n,mmap) }
-
-#if notyet
-#include "lp.h"
-cdev_decl(lp);
-#include "lptwo.h"
-cdev_decl(lptwo);
-#endif /* notyet */
-
-cdev_decl(st);
-cdev_decl(sd);
-cdev_decl(cd);
-cdev_decl(xd);
-cdev_decl(vnd);
-
-#include "bpfilter.h"
-cdev_decl(bpf);
-
-#include "tun.h"
-cdev_decl(tun);
-
-#ifdef LKM
-#define NLKM 1
-#else
-#define NLKM 0
-#endif
-
-cdev_decl(lkm);
-
-struct cdevsw cdevsw[] =
-{
- cdev_cn_init(1,cn), /* 0: virtual console */
- cdev_ctty_init(1,ctty), /* 1: controlling terminal */
-#if notyet
- cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */
-#endif /* notyet */
- cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */
- cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */
- cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
- cdev_log_init(1,log), /* 6: /dev/klog */
-#if notyet
- cdev_mdev_init(NSRAM,sram), /* 7: /dev/sramX */
-#endif /* notyet */
- cdev_disk_init(NSD,sd), /* 8: SCSI disk */
- cdev_disk_init(NCD,cd), /* 9: SCSI CD-ROM */
-#if notyet
- cdev_mdev_init(NNVRAM,nvram), /* 10: /dev/nvramX */
- cdev_mdev_init(NFLASH,flash), /* 11: /dev/flashX */
- cdev_tty_init(NZS,zs), /* 12: SCC serial (tty[a-d]) */
- cdev_tty_init(NCL,cl), /* 13: CL-CD1400 serial (tty0[0-3]) */
-#endif /* notyet */
- cdev_tty_init(NBUGTTY,bugtty), /* 14: BUGtty (ttyB) */
- cdev_notdef(), /* 15 */
- cdev_notdef(), /* 16 */
- cdev_notdef(), /* 17: concatenated disk */
- cdev_notdef(), /* 18 */
- cdev_disk_init(NVND,vnd), /* 19: vnode disk */
- cdev_tape_init(NST,st), /* 20: SCSI tape */
- cdev_fd_init(1,fd), /* 21: file descriptor pseudo-dev */
- cdev_bpftun_init(NBPFILTER,bpf),/* 22: berkeley packet filter */
- cdev_bpftun_init(NTUN,tun), /* 23: network tunnel */
- cdev_lkm_init(NLKM,lkm), /* 24: loadable module driver */
- cdev_notdef(), /* 25 */
-#if notyet
- cdev_disk_init(NXD,xd), /* 26: XD disk */
-#endif /* notyet */
- cdev_notdef(), /* 27 */
-#if notyet
- cdev_lp_init(NLP,lp), /* 28: lp */
- cdev_lp_init(NLPTWO,lptwo), /* 29: lptwo */
-#endif /* notyet */
- cdev_notdef(), /* 30 */
-#if notyet
- cdev_mdev_init(NVMEL,vmel), /* 31: /dev/vmelX */
- cdev_mdev_init(NVMES,vmes), /* 32: /dev/vmesX */
-#endif /* notyet */
- cdev_lkm_dummy(), /* 33 */
- cdev_lkm_dummy(), /* 34 */
- cdev_lkm_dummy(), /* 35 */
- cdev_lkm_dummy(), /* 36 */
- cdev_lkm_dummy(), /* 37 */
- cdev_lkm_dummy(), /* 38 */
-};
-int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
-
-int mem_no = 2; /* major device number of memory special file */
-
-/*
- * Swapdev is a fake device implemented
- * in sw.c used only internally to get to swstrategy.
- * It cannot be provided to the users, because the
- * swstrategy routine munches the b_dev and b_blkno entries
- * before calling the appropriate driver. This would horribly
- * confuse, e.g. the hashing routines. Instead, /dev/drum is
- * provided as a character (raw) device.
- */
-dev_t swapdev = makedev(3, 0);
-
-/*
- * Returns true if dev is /dev/mem or /dev/kmem.
- */
-iskmemdev(dev)
- dev_t dev;
-{
-
- return (major(dev) == mem_no && minor(dev) < 2);
-}
-
-/*
- * Returns true if dev is /dev/zero.
- */
-iszerodev(dev)
- dev_t dev;
-{
-
- return (major(dev) == mem_no && minor(dev) == 12);
-}
-
-static int chrtoblktbl[] = {
- /* XXXX This needs to be dynamic for LKMs. */
- /*VCHR*/ /*VBLK*/
- /* 0 */ NODEV,
- /* 1 */ NODEV,
- /* 2 */ NODEV,
- /* 3 */ NODEV,
- /* 4 */ NODEV,
- /* 5 */ NODEV,
- /* 6 */ NODEV,
- /* 7 */ NODEV,
- /* 8 */ 4, /* SCSI disk */
- /* 9 */ 6, /* SCSI CD-ROM */
- /* 10 */ NODEV,
- /* 11 */ NODEV,
- /* 12 */ NODEV,
- /* 13 */ NODEV,
- /* 14 */ NODEV,
- /* 15 */ NODEV,
- /* 16 */ NODEV,
- /* 17 */ NODEV,
- /* 18 */ NODEV,
- /* 19 */ 8, /* vnode disk */
- /* 20 */ NODEV,
- /* 21 */ NODEV,
- /* 22 */ NODEV,
- /* 23 */ NODEV,
- /* 24 */ NODEV,
- /* 25 */ NODEV,
- /* 26 */ 10, /* XD disk */
-};
-
-/*
- * Convert a character device number to a block device number.
- */
-chrtoblk(dev)
- dev_t dev;
-{
- int blkmaj;
-
- if (major(dev) >= nchrdev ||
- major(dev) >= sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]))
- return (NODEV);
- blkmaj = chrtoblktbl[major(dev)];
- if (blkmaj == NODEV)
- return (NODEV);
- return (makedev(blkmaj, minor(dev)));
-}
-
-/*
- * This entire table could be autoconfig()ed but that would mean that
- * the kernel's idea of the console would be out of sync with that of
- * the standalone boot. I think it best that they both use the same
- * known algorithm unless we see a pressing need otherwise.
- */
-#include <dev/cons.h>
-
-#define zscnpollc nullcnpollc
-cons_decl(zs);
-#define clcnpollc nullcnpollc
-cons_decl(cl);
-#define bugttycnpollc nullcnpollc
-cons_decl(bugtty);
-
-struct consdev constab[] = {
-#if NZS > 0
- cons_init(zs),
-#endif
-#if NCL > 0
- cons_init(cl),
-#endif
-#if NBUGTTY > 0
- cons_init(bugtty),
-#endif
- { 0 },
-};
diff --git a/sys/arch/mvme88k/m88k/continuation.s b/sys/arch/mvme88k/m88k/continuation.s
deleted file mode 100644
index 6f12118be2f..00000000000
--- a/sys/arch/mvme88k/m88k/continuation.s
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * 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 10:54:27 deraadt
- * Initial revision
- *
- * 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/m88k/eh.S b/sys/arch/mvme88k/m88k/eh.S
deleted file mode 100644
index 280267ccc52..00000000000
--- a/sys/arch/mvme88k/m88k/eh.S
+++ /dev/null
@@ -1,1749 +0,0 @@
-/*
- * 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
- * 1. Should get rid of SR0 reference for thread stuff.
- * 2. Make up my mind what is _kstack. I think it
- * should be p->p_addr+UPAGES. (p_addr
- * is pointing to user struct and swapin is
- * making sure it is updated)
- * Whatever is _kstack, its usage in this file should be
- * revisited.
- */
-
- /*
- **************************************************************RCS******
- *
- * -------------------------------------------------------------------
- * | In the following discussion, references are made to: |
- * | MC88100 - RISC MICROPROCESSOR USER'S MANUAL |
- * | (second edition). Reference in []s refer to section numbers. |
- * | |
- * | This discussion assumes that you are at least vaguely familiar |
- * | with 88100 exception handling (chapter 6), the MACH kernel, and |
- * | that you have a brain (and use it while reading this). |
- * | |
- * | I also assume (and hope) that you're not offended by |
- * | frequent misspellings. |
- * | |
- * | Jeffrey Friedl |
- * | jfriedl@rna.ncl.omron.co.jp |
- * | December, 1989 |
- * -------------------------------------------------------------------
- *
- * EXCEPTIONS, INTERRUPTS, and TRAPS
- * ---------------------------------
- * This is the machine exception handler.
- * In the MC88100, various "conditions" cause an exception, where
- * processing momentarily jumps here to "service" the exception,
- * and then continues where it left off.
- *
- * There are a number of different types of exceptions.
- * For example, exception #6 is the privilege violation exception which
- * is raised when the user tries to execute a supervisor-only instruction.
- *
- * Exception #1 is the interrupt exception, and is raised when an
- * outside device raises the INT line on the CPU. This happens,
- * for example, when the clock signals that it is time for a context
- * switch, or perhaps the disk drive signaling that some operation
- * is complete.
- *
- * Traps are also exceptions. Traps are ways for user programs to request
- * kernel operations. For example, "tcnd eq0, r0, 128" will raise
- * exception 128, the system call exception.
- *
- *
- * SERVICING AN EXCEPTION
- * -----------------------
- * When an exception occurs, each control register is saved in its
- * respective shadow register and execution continues from the
- * appropriate exception handler. The exception handler must
- * - save the context from the time of the exception
- * - service the exception
- * - restore the context (registers, etc)
- * - pick up from where the exception occurred.
- *
- * The context is saved on a stack. Actually, in the user_state area
- * in the PCB if the exception happens in user mode.
- *
- * Servicing the exception is usually straightforward and in fact not dealt
- * with very much here. Usually a C routine is called to handle it.
- * For example, when a privilege exception is raised, the routine that sends
- * an "illegal instruction" signal to the offending process is called.
- *
- * When the exception has been serviced, the context is restored from the
- * stack and execution resumes from where it left off.
- *
- * In more detail:
- *
- * Saving the exception-time context.
- * ---------------------------------
- * In saving the exception-time context, we copy the shadow and general
- * purpose registers to memory. Since one exception may occur while
- * servicing another, the memory used to save the exception-time context may
- * not be static (i.e. the same every time). Thus, memory on a stack is set
- * aside for the exception frame (area where the exception-time context is
- * saved). The same stack is also used when C routines are called (to
- * service the exception).
- *
- * Each process has a stack in kernel space (called the "kernel stack",
- * short for "process's kernel stack) as well as the user space stack. When
- * entering the kernel from user space, the kernel stack is unused. On this
- * stack we save the exception state and (most likely call a C routine to)
- * service the exception.
- *
- * Before servicing an exception, several issues must be addressed.
- *
- * 1) When an interrupt is recognized by the hardware, the data pipeline is
- * allowed to clear. However, if one of these data accesses faults (bad
- * reference, or a reference to a page which needs to be swapped in), that
- * reference, as well as any others in the pipeline at the time (at most
- * three total) are left there, to be taken care of by the exception
- * handler [6.4.1]. This involves swapping in the proper page and
- * manually doing the appropriate load or store.
- *
- * The other (at most, two other) data accesses that might have been in
- * the pipeline must also be manually completed (even though they may not
- * be at fault [yes, that's a bad pun, thank you]).
- *
- * 2) If any of the (at most three) uncompleted data access in the pipeline
- * are loads (from memory to a register), then the bit for the destination
- * register is set in the SSBR. Since the hardware will never complete
- * that load (since we do it manually), the hardware will never clear that
- * SSBR bit. Thus, we must clear it manually. If this isn't done, the
- * system will hang waiting for a bit to clear that will never.
- *
- * 3) If the exception is the privilege violation exception, the bounds
- * violation exception, or the misaligned access exception, the
- * destination register bit in the SSBR may need to be cleared.
- *
- * 4) If the exception is one of the floating exceptions, then the
- * destination register for that floating process won't be written,
- * and the SSBR must be cleared explicitly.
- *
- * 5) The FPU must be enabled (as it is disabled by the exception processing
- * hardware) and allowed to complete actions in progress. This is so
- * so that it may be used in the servicing of any instruction.
- * When the FPU is being restarted, operations attempting to complete
- * may themselves fault (raising another exception).
- *
- * More on Restarting the FPU
- * --------------------------
- * The manual [section 6.4.3.4] gives only minor mention to this
- * rather complex task. Before the FPU is restarted all SSBR bits are
- * cleared for actions that the exception handler completes (as mentioned
- * above) so that the SSBR is clear unless there are FPU operations that
- * have not actually been completed (and hence not written to the registers).
- * Also, all control registers (at least all those that we care about) are
- * saved to the stack exception frame before the FPU is restarted (this
- * is important... the reason comes later).
- *
- * The FPU is restarted by doing an rte to a trap-not-taken (the rte
- * actually enables the fpu because we ensure that the EPSR has the
- * FPU-enable bit on; the trap-not-taken ensures anything in the FPU
- * completes by waiting until scoreboard register is clear).
- *
- * At the time the FPU is restarted (the rte to the trap-not-taken) the FPU
- * can write to ANY of the general registers. Thus, we must make sure that
- * all general registers (r1..r31) are in their pre-exception state so that
- * when saved to the exception frame after the FPU is enabled, they properly
- * reflect any changes made by the FPU in being restarted.
- *
- * Because we can't save the pointer to the exception frame in a general
- * register during the FPU restart (it could get overwritten by the FPU!),
- * we save it in a control register, SR3, during the restart.
- *
- *
- * HOWEVER .....
- *
- * Because other uncompleted actions in the FPU may fault when the FPU is
- * restarted, a new exception may be raised during the restart. This may
- * happen recursively a number of times. Thus, during a restart, ANY register
- * whatsoever may be modified, including control registers. Because of this
- * we must make sure that the exception handler preserves SR3 throughout
- * servicing an exception so that, if the exception had been raised during
- * an FPU restart, it is returned unmolested when control returns to the FPU
- * restart.
- *
- * Thus: if an exception is from kernel space, we MUST preserve SR3.
- * (if it from user space, no FPU-enable can be in progress and SR3 is
- * unimportant).
- *
- * Now is a good time to recap SR0..SR3 usage:
- * SR0 -
- * SR1 - CPU flags (exception handler flags)
- * SR2 - generally free
- * SR3 - free only if the exception is from user mode
- *
- * Once the FPU has been restarted, the general registers are saved to the
- * exception frame. If the exception is not the interrupt exception,
- * interrupts are enabled and any faulted data accesses (see above) are
- * serviced. In either case, the exception is then serviced (usually by
- * calling a C routine). After servicing, any faulted data accesses are
- * serviced (if it had been the interrupt exception). The context is then
- * restored and control returns to where the exception occurred.
- *
- */
-
-#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/trap.h> /* for T_ defines */
-#include <machine/locore.h> /* lots of stuff */
-#include <machine/asm.h>
-
-#ifndef PCB_USER
-#define PCB_USER 0
-#endif
-#ifndef NBPG
-#define NBPG 4096
-#endif /* NBPG */
-#ifndef USIZE
-#define USIZE (UPAGES * NBPG)
-#endif /* USIZE */
-
-/*
- * The exception frame as defined in "luna/m88k.h" (among other places) is
- * a bit outdated and needs to be changed. Until then, we'll define some
- * pseudo-fields there for our needs.
- *
- * EF_SR3 A place to save the exception-time SR3 from just after the
- * time when an exception is raised until just after the FPU
- * has been restarted. This does not necessarly conflict with
- * the general registers (though it can if you're not careful)
- * and so we can use a spot later used to save a general register.
- *
- * EF_FLAGS This is just the old EF_MODE. "EF_MODE" isn't a very good name.
- */
-#define EF_SR3 (EF_R0 + 5)
-#define EF_FLAGS EF_MODE
-
-#define FLAG_FROM_KERNEL 8 /* this should be in locore.h */
-
- text
- align 8
-
-/***************************************************************************
- ***************************************************************************
- **
- ** #define PREP(NAME, NUM, BIT, SSBR_STUFF, FLAG_CHECK)
- **
- ** This is the "exception processing preparaton" common to all exception
- ** processing. It is used in the following manor:
- **
- ** LABEL(foo_handler)
- ** PREP("foo", 11, DEBUG_FOO_BIT, No_SSBR_Stuff, No_Precheck)
- ** CALL(_trap, T_FOO_FAULT, r31)
- ** DONE(DEBUG_FOO_BIT)
- **
- ** This defines the exception handler for the "foo" exception.
- ** The arguments ro PREP():
- ** NAME - String for debugging (more info later)
- ** NUM - The exception number [see the manual, Table 6-1]
- ** BIT - Bit to check in eh_debug for debugging (more info later)
- ** SSBR_STUFF -
- ** If the exception might leave some bits in the SSBR set,
- ** this should indicate how they are cleared.
- ** FLAG_PRECHECK -
- ** This is for the data access exception only. See it for
- ** more info.
- **
- **
- ** What's in between PREP() and DONE() (usually a CALL) is the actual
- ** servicing of the interrupt. During this time, any register may
- ** be used freely as they've all been saved in the exception frame
- ** (which is pointed-to by r31).
- **/
-#define PREP(NAME, NUM, BIT, SSBR_STUFF, FLAG_PRECHECK) NEWLINE \
- xcr FLAGS, FLAGS, SR1 NEWLINE \
- FLAG_PRECHECK NEWLINE \
- NEWLINE \
- /* the bsr later clobbers r1, so save now */ NEWLINE \
- stcr r1, SR2 /* r1 now free */ NEWLINE \
- NEWLINE \
- /* set or clear the FLAG_FROM_KERNEL bit */ NEWLINE \
- ldcr r1, EPSR NEWLINE \
- bb0.n PSR_SUPERVISOR_MODE_BIT, r1, 1f NEWLINE \
- clr FLAGS, FLAGS, 1<FLAG_FROM_KERNEL> NEWLINE \
- set FLAGS, FLAGS, 1<FLAG_FROM_KERNEL> NEWLINE \
- NEWLINE \
- /* get a stack (exception frame) */ NEWLINE \
- 1: bsr setup_phase_one NEWLINE \
- NEWLINE \
- /* TMP2 now free -- use to set EF_VECTOR */ NEWLINE \
- or TMP2, r0, NUM NEWLINE \
- st TMP2, r31, REG_OFF(EF_VECTOR) NEWLINE \
- NEWLINE \
- /* Clear any bits in the SSBR (held in TMP) */ NEWLINE \
- /* SSBR_STUFF may be empty, though. */ NEWLINE \
- SSBR_STUFF NEWLINE \
- NEWLINE \
- /* call setup_phase_two to restart the FPU */ NEWLINE \
- /* and to save all general registers. */ NEWLINE \
- bsr setup_phase_two NEWLINE \
- NEWLINE \
- /* All general regs free -- do any debugging */ NEWLINE \
- PREP_DEBUG(BIT, NAME)
-
-#undef EH_DEBUG
-#define EH_DEBUG 1
-
-/* Some defines for use with PREP() */
-#define No_SSBR_Stuff /* empty */
-#define Clear_SSBR_Dest bsr clear_dest_ssbr_bit
-#define No_Precheck /* empty */
-#define Data_Precheck \
- bb1.n FLAG_IGNORE_DATA_EXCEPTION, FLAGS, ignore_data_exception
-
-#if EH_DEBUG
- /*
- * If we allow debugging, there is a variable "eh_debug"
- * in which there is a bit for each exception. If the bit
- * is set for an exception, debugging information is printed
- * about that exception whenever it occurs.
- *
- * The bits are defined in "locore.h"
- */
-/* LABEL(_eh_debug) word 0x00000000 */
- LABEL(_eh_debug) word 0xFFFFFFFF
-
- /*
- * additional pre-servicing preparation to be done when
- * debugging... check eh_debug and make the call if
- * need be.
- */
- #define PREP_DEBUG(DebugNumber, Name) \
- or.u r2, r0, hi16(_eh_debug) NEWLINE \
- ld r3, r2, lo16(_eh_debug) NEWLINE \
- bb0 DebugNumber, r3, 4f NEWLINE \
- /* call MY_info(ef,thread,flags,kind)*/ NEWLINE \
- or r2, r30, r0 NEWLINE \
- ldcr r3, SR0 NEWLINE \
- ldcr r4, SR1 NEWLINE \
- or.u r5, r0, hi16(2f) NEWLINE \
- or r5, r5, lo16(2f) NEWLINE \
- bsr.n _MY_info NEWLINE \
- subu r31, r31, 40 NEWLINE \
- br.n 4f NEWLINE \
- addu r31, r31, 40 NEWLINE \
- data NEWLINE \
- 2: string Name NEWLINE \
- byte 0 NEWLINE \
- align 4 NEWLINE \
- text NEWLINE \
- 4:
-
-
- /*
- * Post-servicing work to be done.
- * When debugging, check "eh_debug" and call the
- * debug routined if neeed be.
- *
- * Then, return from the interrupt handler.
- */
- #define DONE(DebugNumber) \
- or.u r2, r0, hi16(_eh_debug) NEWLINE \
- ld r3, r2, lo16(_eh_debug) NEWLINE \
- bb0 DebugNumber, r3, 2f NEWLINE \
- ldcr r4, SR1 NEWLINE \
- CALL(_MY_info_done, r31, r4) NEWLINE \
- 2: br return_from_exception_handler
-#else
- /*
- * If not debugging, then no debug-prep to do.
- * Also, when you're done, you're done! (no debug check).
- */
- #define PREP_DEBUG(bit, name)
- #define DONE(num) br return_from_exception_handler
-#endif
-
-
-/*#########################################################################*/
-/*#### THE ACTUAL EXCEPTION HANDLER ENTRY POINTS ##########################*/
-/*#########################################################################*/
-
-/* unknown exception handler */
-LABEL(unknown_handler)
- PREP("unknown", 0, DEBUG_UNKNOWN_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_UNKNOWNFLT, r30)
- DONE(DEBUG_UNKNOWN_BIT)
-
-/* interrupt exception handler */
-LABEL(interrupt_handler)
- PREP("interrupt", 1, DEBUG_INTERRUPT_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_ext_int, 1, r30)
- DONE(DEBUG_INTERRUPT_BIT)
-
-/* instruction access exception handler */
-LABEL(instruction_access_handler)
- PREP("inst", 2, DEBUG_INSTRUCTION_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_INSTFLT, r30)
-#if 0
- /* done in trap now */
- /*
- * Now, to retry the instruction.
- * Copy the SNIP to the SFIP, clearing the E bit.
- * Copy the SXIP to the SNIP, clearing the E bit.
- */
- ld r1, r30, REG_OFF(EF_SNIP)
- ld r2, r30, REG_OFF(EF_SXIP)
- clr r1, r1, 1<RTE_ERROR_BIT>
- clr r2, r2, 1<RTE_ERROR_BIT>
- st r1, r30, REG_OFF(EF_SFIP)
- st r2, r30, REG_OFF(EF_SNIP)
-#endif /* 0 */
- DONE(DEBUG_INSTRUCTION_BIT)
-
-/*
- * data access exception handler --
- * See badaddr() below for info about Data_Precheck.
- */
-LABEL(data_exception_handler)
- PREP("data", 3, DEBUG_DATA_BIT, No_SSBR_Stuff, Data_Precheck)
- DONE(DEBUG_DATA_BIT)
-
-/* misaligned access exception handler */
-LABEL(misaligned_handler)
- PREP("misalign", 4, DEBUG_MISALIGN_BIT, Clear_SSBR_Dest, No_Precheck)
- CALL(_trap, T_MISALGNFLT, r30)
- DONE(DEBUG_MISALIGN_BIT)
-
-/* unimplemented opcode exception handler */
-LABEL(unimplemented_handler)
- PREP("unimp", 5, DEBUG_UNIMPLEMENTED_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_ILLFLT, r30)
- DONE(DEBUG_UNIMPLEMENTED_BIT)
-
-/*
- * Some versions of the chip have * a bug whereby false privilege
- * violation exceptions are raised. If the valid bit in the SXIP is clear,
- * it is false. If so, just return. The code before PREP handles this....
- */
-LABEL(privilege_handler)
- stcr r1, SR2 /* hold r1 for a moment */
- ldcr r1, SXIP /* look at the sxip... valid bit set? */
- bb1.n RTE_VALID_BIT, r1, 1f /*skip over return if a valid exception*/
- ldcr r1, SR2 /* restore r1 */
- RTE
- 1: PREP("privilege", 6, DEBUG_PRIVILEGE_BIT, Clear_SSBR_Dest, No_Precheck)
- CALL(_trap, T_PRIVINFLT, r30)
- DONE(DEBUG_PRIVILEGE_BIT)
-
-/*
- * I'm not sure what the trap(T_BNDFLT,...) does, but it doesn't send
- * a signal to the process...
- */
-LABEL(bounds_handler)
- PREP("bounds", 7, DEBUG_BOUNDS_BIT, Clear_SSBR_Dest, No_Precheck)
- CALL(_trap, T_BNDFLT, r30)
- DONE(DEBUG_BOUNDS_BIT)
-
-/* integer divide-by-zero exception handler */
-LABEL(divide_handler)
- PREP("divide", 8, DEBUG_DIVIDE_BIT, Clear_SSBR_Dest, No_Precheck)
- CALL(_trap, T_ZERODIV, r30)
- DONE(DEBUG_DIVIDE_BIT)
-
-/* integer overflow exception handelr */
-LABEL(overflow_handler)
- PREP("overflow", 9, DEBUG_OVERFLOW_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_OVFFLT, r30)
- DONE(DEBUG_OVERFLOW_BIT)
-
-/* Floating-point precise handler */
-#define FPp_SSBR_STUFF bsr clear_FPp_ssbr_bit
-LABEL(fp_precise_handler)
- PREP("FPU precise", 114, DEBUG_FPp_BIT, FPp_SSBR_STUFF, No_Precheck)
- CALL(_Xfp_precise, r0, r30) /* call fp_precise(??, exception_frame)*/
- DONE(DEBUG_FPp_BIT)
-
-/* Floating-point imprecise handler */
-#define FPi_SSBR_STUFF bsr clear_FPi_ssbr_bit
-LABEL(fp_imprecise_handler)
- PREP("FPU imprecise", 115, DEBUG_FPi_BIT, FPi_SSBR_STUFF, No_Precheck)
- CALL(_Xfp_imprecise, r0, r30) /*call fp_imprecise(??,exception_frame)*/
- DONE(DEBUG_FPi_BIT)
-
-/* All standard system calls. */
-LABEL(syscall_handler)
- PREP("syscall", 128, DEBUG_SYSCALL_BIT, No_SSBR_Stuff, No_Precheck)
- ld r13, r30, GENREG_OFF(13)
- CALL(_syscall, r13, r30) /* system call no. is in r13 */
- DONE(DEBUG_SYSCALL_BIT)
-
-/* trap 496 comes here */
-LABEL(_bugtrap)
- PREP("bugsyscall", 496, DEBUG_BUGCALL_BIT, No_SSBR_Stuff, No_Precheck)
- ld r9, r30, GENREG_OFF(9)
- CALL(_bugsyscall, r9, r30) /* system call no. is in r9 */
- DONE(DEBUG_SYSCALL_BIT)
-
-LABEL(_sigsys)
- PREP("sigsys", 0, DEBUG_SIGSYS_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_SIGSYS, r30)
- DONE(DEBUG_SIGSYS_BIT)
-
-LABEL(_sigtrap)
- PREP("sigtrap", 0, DEBUG_SIGTRAP_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_SIGTRAP, r30)
- DONE(DEBUG_SIGTRAP_BIT)
-
-LABEL(_stepbpt)
- PREP("sigtrap", 0, DEBUG_SIGTRAP_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_STEPBPT, r30)
- DONE(DEBUG_SIGTRAP_BIT)
-
-LABEL(_userbpt)
- PREP("sigtrap", 0, DEBUG_SIGTRAP_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_USERBPT, r30)
- DONE(DEBUG_SIGTRAP_BIT)
-
-#if DDB
- LABEL(break)
- PREP("break", 130, DEBUG_BREAK_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_KDB_BREAK, r30)
- DONE(DEBUG_BREAK_BIT)
- LABEL(trace)
- PREP("trace", 131, DEBUG_TRACE_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_KDB_TRACE, r30)
- DONE(DEBUG_TRACE_BIT)
- LABEL(entry)
- PREP("kdb", 132, DEBUG_KDB_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_KDB_ENTRY, r30)
- DONE(DEBUG_KDB_BIT)
-#else /* else not DDB */
- LABEL(break)
- PREP("break", 130, DEBUG_BREAK_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_UNKNOWNFLT, r30)
- DONE(DEBUG_BREAK_BIT)
- LABEL(trace)
- PREP("trace", 131, DEBUG_TRACE_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_UNKNOWNFLT, r30)
- DONE(DEBUG_TRACE_BIT)
- LABEL(entry)
- PREP("unknown", 132, DEBUG_UNKNOWN_BIT, No_SSBR_Stuff, No_Precheck)
- CALL(_trap, T_UNKNOWNFLT, r30)
- DONE(DEBUG_KDB_BIT)
-#endif /* DDB */
-
-
-/*--------------------------------------------------------------------------*/
-
-/*
- * The error exception handler.
- * The error exception is raised when any other non-trap exception is raised
- * while shadowing is off. This is Bad News.
- *
- * The shadow registers are not valid in this case (shadowing was off, ne).
- * R1-R31 may be interesting though, so we'll save them.
- *
- * We'll not worry about trashing r26-29 here,
- * since they aren't generally used.
- */
-LABEL(error_handler)
- /* pick up the slavestack */
- or r26, r0, r31 /* save old stack */
- or.u r31, r0, hi16(_intstack_end)
- or r31, r31, lo16(_intstack_end)
-
- /* zero the stack, so we'll know what we're lookin' at */
- or.u r27, r0, hi16(_intstack)
- or r27, r27, lo16(_intstack)
- 1: cmp r28, r27, r31
- bb1 ge, r28, 2f /* branch if at the end of the stack */
- st r0, r0, r27
- br.n 1b
- addu r28, r27, 4 /* bump up */
- 2: /* stack has been cleared */
-
- /* ensure that stack is 8-byte aligned */
- clr r31, r31, 3<0> /* round down to 8-byte boundary */
-
- /* create exception frame on stack */
- subu r31, r31, SIZEOF_EF /* r31 now our E.F. */
-
- /* save old R31 and other R registers */
- st.d r0 , r31, GENREG_OFF(0)
- st.d r2 , r31, GENREG_OFF(2)
- st.d r4 , r31, GENREG_OFF(4)
- st.d r6 , r31, GENREG_OFF(6)
- st.d r8 , r31, GENREG_OFF(8)
- st.d r10, r31, GENREG_OFF(10)
- st.d r12, r31, GENREG_OFF(12)
- st.d r14, r31, GENREG_OFF(14)
- st.d r16, r31, GENREG_OFF(16)
- st.d r18, r31, GENREG_OFF(18)
- st.d r20, r31, GENREG_OFF(20)
- st.d r22, r31, GENREG_OFF(22)
- st.d r24, r31, GENREG_OFF(24)
- st r30, r31, GENREG_OFF(30)
- st r26, r31, GENREG_OFF(31)
-
- /* save shadow registers (are OLD, though) */
- ldcr r10, SXIP
- st r10, r31, REG_OFF(EF_SXIP)
- ldcr r10, SFIP
- st r10, r31, REG_OFF(EF_SFIP)
- ldcr r10, SNIP
- st r10, r31, REG_OFF(EF_SNIP)
- ldcr r10, SSBR
- st r10, r31, REG_OFF(EF_SSBR)
- ldcr r10, EPSR
- st r10, r31, REG_OFF(EF_EPSR)
-
- ldcr r10, DMT0
- st r10, r31, REG_OFF(EF_DMT0)
- ldcr r11, DMD0
- st r11, r31, REG_OFF(EF_DMD0)
- ldcr r12, DMA0
- st r12, r31, REG_OFF(EF_DMA0)
-
- ldcr r10, DMT1
- st r10, r31, REG_OFF(EF_DMT1)
- ldcr r11, DMD1
- st r11, r31, REG_OFF(EF_DMD1)
- ldcr r12, DMA1
- st r12, r31, REG_OFF(EF_DMA1)
-
- ldcr r10, DMT2
- st r10, r31, REG_OFF(EF_DMT2)
- ldcr r11, DMD2
- st r11, r31, REG_OFF(EF_DMD2)
- ldcr r12, DMA2
- st r12, r31, REG_OFF(EF_DMA2)
-
- ldcr r10, SR1
- st r10, r31, REG_OFF(EF_MODE)
-
- /* shove sr2 into EF_FPLS1 */
- ldcr r10, SR2
- st r10, r31, REG_OFF(EF_FPLS1)
-
- /* shove sr3 into EF_FPHS2 */
- ldcr r10, SR3
- st r10, r31, REG_OFF(EF_FPHS2)
-
- /* error vector is zippo numero el'zeroooo */
- st r0, r31, REG_OFF(EF_VECTOR)
-
- stcr r0, SSBR /* won't want shadow bits bothering us later */
-
- /*
- * Cheap way to enable FPU and start shadowing again.
- */
- ldcr r10, PSR
- clr r10, r10, 1<PSR_FPU_DISABLE_BIT> /* enable the FPU */
- clr r10, r10, 1<PSR_SHADOW_FREEZE_BIT> /* also enable shadowing */
-
- stcr r10, PSR /* bang */
- FLUSH_PIPELINE
-
- /* put pointer to regs into r30... r31 will become a simple stack */
- or r30, r31, r0
-
- subu r31, r31, 0x10 /* make some breathing space */
- st r30, r31, 0x0c /* store frame pointer on the st */
- st r30, r31, 0x08 /* store again for the debugger to recognize */
- or.u r20, r0, hi16(0x87654321)
- or r20, r20, lo16(0x87654321)
- st r20, r31, 0x04
- st r20, r31, 0x00
-
- CALL(_error_fault, r30, r30)
-
- /* TURN INTERUPTS back on */
- ldcr r1, PSR
- clr r1, r1, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r1, PSR
- FLUSH_PIPELINE
-LABEL(_error_loop) bsr _error_loop
- /* never returns*/
-
-/*
- *----------------------------------------------------------------------------
- *----------------------------------------------------------------------------
- *----------------------------------------------------------------------------
- */
-
-
-/*
- * This is part of baddadr (below).
- */
-_LABEL(ignore_data_exception)
- /******************************************************\
- * SR0: pointer to the current thread structure *
- * SR1: previous FLAGS reg *
- * SR2: free *
- * SR3: must presere *
- * FLAGS: CPU status flags *
- \******************************************************/
- xcr FLAGS, FLAGS, SR1 /* replace SR1, FLAGS */
-
- /*
- * For more info, see badaddr() below.
- *
- * We just want to jump to "badaddr__return_nonzero" below.
- *
- * We don't worry about trashing R2 here because we're
- * jumping back to the function badaddr() where we're allowd
- * to blast r2..r9 as we see fit.
- */
-
- /* the "+2" below is to set the VALID bit. */
- or.u r2, r0, hi16(badaddr__return_nonzero + 2)
- or r2, r2, lo16(badaddr__return_nonzero + 2)
- stcr r2, SNIP /* Make it the next instruction to execute */
- addu r2, r2, 4
- stcr r2, SFIP /* and the next one after that, too. */
- stcr r0, SSBR /* make the scoreboard happy. */
-
- /* the following jumps to "badaddr__return_nonzero" in below */
- RTE
-
-/*
- * extern boolean_t badaddr(unsigned addr, unsigned len)
- *
- * Returns true (non-zero) if the given LEN bytes starting at ADDR are
- * not all currently accessable by the kernel.
- *
- * If all LEN bytes starting at ADDR are accessable, zero is returned.
- *
- * Len may be be 1, 2, or 4.
- *
- * This is implementd by setting a special flag in SR1 before trying to access
- * the given address. If a data access exception is raised, the address
- * is inaccessable. The exception handler will notice the special CPU flag
- * and not try to swap the address in. Rather, it will return to
- * "badaddr__return_nonzero" in this routine so that we may return non-zero
- * to the calling routine.
- *
- * If no fault is raised, we continue to where we return zero to the calling
- * routine (after removing the special CPU flag).
- */
-
-LABEL(_badaddr)
- /*
- * Disable interrupts ... don't want a context switch while we're
- * doing this! Also, save the old PSR in R8 to restore later.
- */
- ldcr r8, PSR
- set r4, r8, 1<PSR_INTERRUPT_DISABLE_BIT>
- FLUSH_PIPELINE
- stcr r4, PSR
-
- ldcr r5, SR1
- set r5, r5, 1<FLAG_IGNORE_DATA_EXCEPTION>
- /* resetting r5 to SR1 done in the delay slot below. */
-
- /*
- * If it's a word we're doing, do that here. Otherwise,
- * see if it's a halfword.....
- */
- sub r6, r3, 4
- bcnd.n ne0, r6, badaddr__maybe_halfword
- stcr r5, SR1
- FLUSH_PIPELINE
-
- /*
- * It's a bad address if it's misaligned.
- */
- bb1 0, r2, badaddr__return_nonzero
- bb1 1, r2, badaddr__return_nonzero
- /*
- * The next line will either fault or not. If it faults, execution
- * will go to: data_access_handler (see above)
- * and then to: ignore_data_exception (see above)
- * and then to: badaddr__return_nonzero (see below)
- * which will return to the calling function.
- *
- * If there is no fault, execution just continues as normal.
- */
- ld r5, r2, 0
- FLUSH_PIPELINE
- br.n badaddr__return
- or r2, r0, r0 /* indicate a zero (address not bad) return.*/
-
- badaddr__maybe_halfword:
- /* More or less like the code for checking a word above */
- sub r6, r3, 2
- bcnd ne0, r6, badaddr__maybe_byte
-
- /* it's bad if it's misaligned */
- bb1 0, r2, badaddr__return_nonzero
-
- FLUSH_PIPELINE
- ld.h r5, r2, 0
- FLUSH_PIPELINE
- br.n badaddr__return
- or r2, r0, r0
-
- badaddr__maybe_byte:
- /* More or less like the code for checking a word above */
- sub r6, r3, 1
- bcnd ne0, r6, badaddr__unknown_size
- FLUSH_PIPELINE
- ld.b r5, r2, 0
- FLUSH_PIPELINE
- br.n badaddr__return
- or r2, r0, r0
- badaddr__unknown_size:
-#ifndef NDEBUG
- data
- 1: string "bad length (%d) to badaddr() from 0x%x\n\000"
- text
- or.u r2, r0, hi16(1b)
- or r2, r2, lo16(1b)
- or r4, r0, r1
- bsr _printf
- or.u r2, r0, hi16(1b)
- or r2, r2, lo16(1b)
- bsr _panic
- /*NOTREACHED*/
-#endif
-
-_LABEL(badaddr__return_nonzero)
- or r2, r0, 1
- /* fall through to badaddr__return */
-
-_LABEL(badaddr__return)
- ldcr r4, SR1
- clr r4, r4, 1<FLAG_IGNORE_DATA_EXCEPTION>
- stcr r4, SR1
-
- /*
- * Restore the PSR to what it was before.
- * The only difference is that we might be enabling interrupts
- * (which we turned off above). If interrupts were already off,
- * we do not want to turn them on now, so we just restore from
- * where we saved it.
- */
- FLUSH_PIPELINE
- stcr r8, PSR
- jmp r1
-
-
-/*
-******************************************************************************
-******************************************************************************
-******************************************************************************
-*/
-
-
-LABEL(setup_phase_one)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread (if any, null if not) *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: saved copy of exception-time r1 *
- * SR3: must be preserved .. may be the exception-time stack *
- * r1: return address to calling exception handler *
- * FLAGS: CPU status flags *
- *************************************************** *
- * immediate goal: *
- * Decide where we're going to put the exception frame. *
- * Might be at the end of R31, SR3, or the thread's *
- * pcb. *
- \***************************************************************/
-
- /* Check if we are coming in from a FPU restart exception.
- If so, the pcb will be in SR3 */
- bb1.n FLAG_ENABLING_FPU, FLAGS, use_SR3_pcb
- xcr r1, r1, SR2
- /* are we coming in from user mode? If so, pick up thread pcb */
- bb0 FLAG_FROM_KERNEL, FLAGS, pickup_stack
-
- /* Interrupt in kernel mode, not FPU restart */
- _LABEL(already_on_kernel_stack)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread (if any, null if not) *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: return address to the calling exception handler *
- * SR3: must be preserved; may be important for other exceptions *
- * FLAGS: CPU status flags *
- *************************************************** *
- * immediate goal: *
- * We're already on the kernel stack, but not having *
- * needed to use SR3. We can just make room on the *
- * stack (r31) for our exception frame. *
- \***************************************************************/
- subu r31, r31, SIZEOF_EF /* r31 now our E.F. */
- st FLAGS, r31, REG_OFF(EF_FLAGS) /* save flags */
- st r1, r31, GENREG_OFF(1) /* save prev. r1 (now r1 free)*/
-
- ldcr r1, SR3 /* save previous SR3 */
- st r1, r31, REG_OFF(EF_SR3)
-
- addu r1, r31, SIZEOF_EF /* save previous r31 */
- br.n have_pcb
- st r1, r31, GENREG_OFF(31)
-
-
- _LABEL(use_SR3_pcb)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread (if any, null if not) *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: return address to the calling exception handler *
- * SR3: must be preserved; exception-time stack pointer *
- * FLAGS: CPU status flags *
- *************************************************** *
- * immediate goal: *
- * An exception occured while enabling the FPU. Since r31 *
- * is the user's r31 while enabling the FPU, we had put *
- * our pcb pointer into SR3, so make room from *
- * there for our stack pointer. *
- * We need to check if SR3 is the old stack pointer or the *
- * pointer off to the user pcb. If it pointing to the user *
- * pcb, we need to pick up the kernel stack. Otherwise *
- * we need to allocate a frame upon it. *
- * We look at the EPSR to see if it was from user mode *
- * Unfortunately, we have no registers free at the moment *
- * But we know register 0 in the pcb frame will always be *
- * zero, so we can use it as scratch storage. *
- * *
- * *
- \***************************************************************/
- xcr r30, r30, SR3 /* r30 = old exception frame */
- st r1, r30, GENREG_OFF(0) /* free up r1 */
- ld r1, r30, REG_OFF(EF_EPSR) /* get back the epsr */
- bb0.n PSR_SUPERVISOR_MODE_BIT, r1, 1f /* if user mode */
- ld r1, r30, GENREG_OFF(0) /* restore r1 */
- /* we were in kernel mode - dump frame upon the stack */
- st r0, r30, GENREG_OFF(0) /* repair old frame */
- subu r30, r30, SIZEOF_EF /* r30 now our E.F. */
- st FLAGS, r30, REG_OFF(EF_FLAGS) /* save flags */
- st r1, r30, GENREG_OFF(1) /* save prev. r1 (now r1 free) */
-
- st r31, r30, GENREG_OFF(31) /* save previous r31 */
- or r31, r0, r30 /* make r31 our pointer. */
- addu r30, r30, SIZEOF_EF /* r30 now has previous SR3 */
- st r30, r31, REG_OFF(EF_SR3) /* save previous SR3 */
- br.n have_pcb
- xcr r30, r30, SR3 /* restore r30 */
- 1:
- /* we took an exception while restarting the FPU from user space.
- Consequently, we never picked up a stack. Do so now.
- R1 is currently free (saved in the exception frame pointed at by
- r30) */
- or.u r1, r0, hi16(_kstack)
- ld r1, r1, lo16(_kstack)
- addu r1, r1, USIZE-SIZEOF_EF
- st FLAGS, r1, REG_OFF(EF_FLAGS) /* store flags */
- st r31, r1, GENREG_OFF(31) /* store r31 - now free */
- st r30, r1, REG_OFF(EF_SR3) /* store old SR3 (pcb) */
- or r31, r1, r0 /* make r31 our exception frame pointer */
- ld r1, r30, GENREG_OFF(0) /* restore old r1 */
- st r0, r30, GENREG_OFF(0) /* repair that frame */
- st r1, r31, GENREG_OFF(1) /* store r1 in its proper place */
- br.n have_pcb
- xcr r30, r30, SR3 /* restore r30 */
-
- _LABEL(pickup_stack)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: return address to the calling exception handler *
- * SR3: free *
- * FLAGS: CPU status flags *
- *************************************************** *
- * immediate goal: *
- * Since we're servicing an exception from user mode, we *
- * know that SR3 is free. We use it to free up a temp. *
- * register to be used in getting the thread's pcb *
- \***************************************************************/
- stcr r31, SR3 /* save previous r31 */
-
- /* switch to the thread's kernel stack. */
- or.u r31, r0, hi16(_curpcb)
- ld r31, r31, lo16(_curpcb)
- addu r31, r31, PCB_USER /* point to user save area */
- st FLAGS, r31, REG_OFF(EF_FLAGS) /* save flags */
- st r1, r31, GENREG_OFF(1) /* save prev. r1 (now r1 free)*/
- ldcr r1, SR3 /* save previous r31 */
- st r1, r31, GENREG_OFF(31)
- /*FALLTHROUGH */
-
- _LABEL(have_pcb)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: return address to the calling exception handler *
- * SR3: free *
- * r1: free *
- * FLAGS: CPU status flags *
- * r31: our exception frame *
- * Valid in the exception frame: *
- * Exception-time r1, r31, FLAGS. *
- * Exception SR3, if appropriate. *
- *************************************************** *
- * immediate goal: *
- * Save the shadow registers that need to be saved to *
- * the exception frame. *
- \***************************************************************/
- stcr TMP, SR3 /* free up TMP, TMP2, TMP3 */
- SAVE_TMP2
- SAVE_TMP3
-
- /* save some exception-time registers to the exception frame */
- ldcr TMP, EPSR
- ldcr TMP2, SFIP
- ldcr TMP3, SNIP
- st TMP, r31, REG_OFF(EF_EPSR)
- st TMP2, r31, REG_OFF(EF_SFIP)
- st TMP3, r31, REG_OFF(EF_SNIP)
-
- ldcr TMP, SSBR
- ldcr TMP2, SXIP
- ldcr TMP3, DMT0
- st TMP2, r31, REG_OFF(EF_SXIP)
-
-#if 0
- /*
- * The following is a kludge so that
- * a core file will have a copy of
- * DMT0 so that 'sim' can display it
- * correctly.
- * After a data fault has been noticed,
- * the real EF_DTM0 is cleared, so I need
- * to throw this somewhere.
- * There's no special reason I chose this
- * register (FPIT)... it's just one of many
- * for which it causes no pain to do this.
- */
- st TMP3, r31, REG_OFF(EF_FPIT)
-#endif
-
- /*
- * The above shadow registers are obligatory for any and all
- * exceptions. Now, if the data access pipeline is not clear,
- * we must save the DMx shadow registers, as well as clear
- * the appropriate SSBR bits for the destination registers of
- * loads or xmems.
- */
- bb0.n DMT_VALID_BIT, TMP3, DMT_check_finished
- st TMP3, r31, REG_OFF(EF_DMT0)
-
- ldcr TMP2, DMT1
- ldcr TMP3, DMT2
- st TMP2, r31, REG_OFF(EF_DMT1)
- st TMP3, r31, REG_OFF(EF_DMT2)
-
- ldcr TMP2, DMA0
- ldcr TMP3, DMA1
- st TMP2, r31, REG_OFF(EF_DMA0)
- st TMP3, r31, REG_OFF(EF_DMA1)
-
- ldcr TMP2, DMA2
- ldcr TMP3, DMD0
- st TMP2, r31, REG_OFF(EF_DMA2)
- st TMP3, r31, REG_OFF(EF_DMD0)
-
- ldcr TMP2, DMD1
- ldcr TMP3, DMD2
- st TMP2, r31, REG_OFF(EF_DMD1)
- st TMP3, r31, REG_OFF(EF_DMD2)
-
- /*
- *---------------------------------------------------------------
- * need to clear "appropriate" bits in the SSBR before
- * we restart the FPU
- */
-
-
- _LABEL(check_DMT0)
- ldcr TMP2, DMT0
- bb0.n DMT_VALID_BIT, TMP2, DMT_check_finished
- stcr r0, DMT0 /* so an exception at fpu_enable doesn't see our DMT0*/
- bb1 DMT_LOCK_BIT, TMP2, do_DMT0
- bb1 DMT_WRITE_BIT, TMP2, check_DMT1
- _LABEL(do_DMT0)
- extu TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
- set TMP2, TMP2, 1<5>
- clr TMP, TMP, TMP2
-
- _LABEL(check_DMT1)
- ldcr TMP2, DMT1
- bb0 DMT_VALID_BIT, TMP2, check_DMT2
- bb1 DMT_LOCK_BIT, TMP2, do_DMT1
- bb1 DMT_WRITE_BIT, TMP2, check_DMT2
- _LABEL(do_DMT1)
- extu TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
- set TMP2, TMP2, 1<5>
- clr TMP, TMP, TMP2
-
- _LABEL(check_DMT2)
- ldcr TMP2, DMT2
- bb0 DMT_VALID_BIT, TMP2, DMT_check_finished
- bb1 DMT_LOCK_BIT, TMP2, do_DMT2_single
- bb1 DMT_WRITE_BIT, TMP2, DMT_check_finished
- bb1 DMT_DOUBLE_BIT,TMP2, do_DMT2_double
- _LABEL(do_DMT2_single)
- extu TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
- br.n 1f
- set TMP2, TMP2, 1<5>
- _LABEL(do_DMT2_double)
- extu TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
- set TMP2, TMP2, 1<6>
-1: clr TMP, TMP, TMP2
-
- _LABEL(DMT_check_finished)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: return address to the calling exception handler *
- * SR3: saved TMP *
- * r1: free *
- * TMP: possibly revised SSBR *
- * TMP2: free *
- * TMP3: free *
- * FLAGS: CPU status flags *
- * r31: exception frame *
- * Valid in the exception frame: *
- * Exception-time r1, r31, FLAGS. *
- * Exception-time TMP2, TMP3. *
- * Exception-time espr, sfip, snip, sxip. *
- * Dmt0. *
- * Other data pipeline control registers, if appropriate. *
- * Exception SR3, if appropriate. *
- \***************************************************************/
- ldcr r1, SR2
- jmp r1 /* return to allow the handler to clear more SSBR bits */
-
-/************************************************************************/
-/************************************************************************/
-
- _LABEL(clear_FPi_ssbr_bit)
- /*
- * Clear floatingpont-imprecise ssbr bits.
- * Also, save appropriate FPU control registers to the E.F.
- *
- * r1: return address to calling exception handler
- * TMP : (possibly) revised ssbr
- * TMP2 : free
- * TMP3 : free
- */
- fldcr TMP2, FPSR
- fldcr TMP3, FPCR
- st TMP2, r31, REG_OFF(EF_FPSR)
- st TMP3, r31, REG_OFF(EF_FPCR)
-
- fldcr TMP2, FPECR
- fldcr TMP3, FPRH
- st TMP2, r31, REG_OFF(EF_FPECR)
- st TMP3, r31, REG_OFF(EF_FPRH)
-
- fldcr TMP2, FPIT
- fldcr TMP3, FPRL
- st TMP2, r31, REG_OFF(EF_FPIT)
- st TMP3, r31, REG_OFF(EF_FPRL)
-
- /*
- * We only need clear the bit in the SSBR for the
- * 2nd reg of a double result [see section 6.8.5]
- */
- #define FPIT_SIZE_BIT 10
- bb0 FPIT_SIZE_BIT, TMP2, not_double_fpi
- extu TMP2, TMP2, 5<0> /* get the reg. */
- set TMP2, TMP2, 1<6> /* set width (width=2 will clear two bits) */
- clr TMP, TMP, TMP2
-
- _LABEL(not_double_fpi)
- jmp r1
-
-
-/************************************************************************/
-/************************************************************************/
-
-
- _LABEL(clear_FPp_ssbr_bit)
- /*
- * Clear floating pont precise ssbr bits.
- * Also, save appropriate FPU control registers to the E.F.
- *
- * r1: return address to calling exception handler
- * TMP : (possibly) revised ssbr
- * TMP2 : free
- * TMP3 : free
- */
- fldcr TMP2, FPSR
- fldcr TMP3, FPCR
- st TMP2, r31, REG_OFF(EF_FPSR)
- st TMP3, r31, REG_OFF(EF_FPCR)
-
- fldcr TMP2, FPHS1
- fldcr TMP3, FPHS2
- st TMP2, r31, REG_OFF(EF_FPHS1)
- st TMP3, r31, REG_OFF(EF_FPHS2)
-
- fldcr TMP2, FPLS1
- fldcr TMP3, FPLS2
- st TMP2, r31, REG_OFF(EF_FPLS1)
- st TMP3, r31, REG_OFF(EF_FPLS2)
-
- fldcr TMP2, FPPT
- fldcr TMP3, FPECR
- st TMP2, r31, REG_OFF(EF_FPPT)
- st TMP3, r31, REG_OFF(EF_FPECR)
-
- #define FPPT_SIZE_BIT 5
- bb1.n FPPT_SIZE_BIT, TMP2, 1f
- extu TMP3, TMP2, 5<0> /* get FP operation dest reg */
- br.n 2f
- set TMP3, TMP3, 1<5> /* set size=1 -- clear one bit for "float" */
- 1: set TMP3, TMP3, 1<6> /* set size=2 -- clear two bit for "double" */
- 2:
- clr TMP, TMP, TMP3 /* clear bit(s) in ssbr. */
- jmp r1
-
-
-/************************************************************************/
-/************************************************************************/
-
-
- _LABEL(clear_dest_ssbr_bit)
- /*
- * There are various cases where an exception can leave the
- * destination register's bit in the SB set.
- * Examples:
- * misaligned or privilege exception on a LD or XMEM
- * DIV or DIVU by zero.
- *
- * I think that if the instruction is LD.D, then two bits must
- * be cleared.
- *
- * Even though there are a number of instructions/exception
- * combinations that could fire this code up, it's only required
- * to be run for the above cases. However, I don't think it'll
- * ever be a problem to run this in other cases (ST instructions,
- * for example), so I don't bother checking. If we had to check
- * for every possible instruction, this code would be much larger.
- *
- * The only checking, then, is to see if it's a LD.D or not.
- *
- * At the moment....
- * r1: return address to calling exception handler
- * TMP : (possibly) revised ssbr
- * TMP2 : free
- * TMP3 : free
- */
- ldcr TMP3, EPSR /* going to check: user or system memory? */
- ldcr TMP2, SXIP /* get the instruction's address */
- bb1.n PSR_SUPERVISOR_MODE_BIT, TMP3, 2f
- clr TMP2, TMP2, 2<0> /* get rid of valid and error bits. */
-
- 1: /* user space load here */
-#if ERRATA__XXX_USR
- NOP
- ld.usr TMP2, TMP2, r0 /* get the instruction itself */
- NOP
- NOP
- NOP
- br 3f
-#else
- br.n 3f
- ld.usr TMP2, TMP2, r0 /* get the instruction itself */
-#endif
-
- 2: /* system space load here */
- ld TMP2, TMP2, r0 /* get the instruction itself */
-
- 3: /* now have the instruction..... */
- /*
- * Now see if it's a double load
- * There are three forms of double load [IMM16, scaled, unscaled],
- * which can be checked by matching against two templates:
- * -- 77776666555544443333222211110000 --
- * if (((instruction & 11111100000000000000000000000000) ==
- * 00010000000000000000000000000000) ||
- * ((instruction & 11111100000000001111110011100000) ==
- * 11110100000000000001000000000000))
- * {
- * It's a load double, so
- * clear two SSBR bits.
- * }
- * else
- * {
- * It's not a load double.
- * Must be a load single, xmem, or st
- * Thus, clear one SSBR bit.
- * }
- */
- /* check the first pattern for ld.d */
- extu TMP3, TMP2, 16<16> /* get the upper 16 bits */
- mask TMP3, TMP3, 0xFC00 /* apply the mask */
- cmp TMP3, TMP3, 0x1000 /* if this is equal, it's a load double */
- bb1 eq, TMP3, misaligned_double
-
- /* still could be -- check the second pattern for ld.d */
- /* look at the upper 16 bits first */
- extu TMP3, TMP2, 16<16> /* get the upper 16 bits */
- mask TMP3, TMP3, 0xFC00 /* apply the mask */
- cmp TMP3, TMP3, 0xF400 /* if equal, it might be a load double */
- bb1 ne, TMP3, misaligned_single /* not equal, so must be single */
-
- /* now look at the lower 16 bits */
- extu TMP3, TMP2, 16<0> /* get the lower 16 bits */
- mask TMP3, TMP3, 0xFCE0 /* apply the mask */
- cmp TMP3, TMP3, 0x1000 /* if this is equal, it's a load double */
- bb1 eq, TMP3, misaligned_double
-
- _LABEL(misaligned_single)
- extu TMP2, TMP2, 5<21> /* get the destination register */
- br.n 1f
- set TMP2, TMP2, 1<5> /* set size=1 */
-
- _LABEL(misaligned_double)
- extu TMP2, TMP2, 5<21> /* get the destination register */
- set TMP2, TMP2, 1<6> /* set size=2 -- clear two bit for "ld.d" */
-
- 1: jmp.n r1
- clr TMP, TMP, TMP2 /* clear bit(s) in ssbr. */
-
-/************************************************************************/
-/************************************************************************/
-
-
-
- LABEL(setup_phase_two)
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: saved copy of exception-time register now holding FLAGS *
- * SR2: free *
- * SR3: saved TMP *
- * r1: return address to calling exception handler *
- * TMP: possibly revised SSBR *
- * TMP2: free *
- * TMP3: free *
- * FLAGS: CPU status flags *
- * r31: our exception frame *
- * Valid in the exception frame: *
- * Exception-time r1, r31, FLAGS. *
- * Exception-time TMP2, TMP3. *
- * Exception-time espr, sfip, snip, sxip. *
- * Exception number (EF_VECTOR). *
- * Dmt0 *
- * Other data pipeline control registers, if appropriate. *
- * FPU control registers, if appropriate. *
- * Exception SR3, if appropriate. *
- *************************************************** *
- * immediate goal: *
- * restore the system to the exception-time state (except *
- * SR3 will be OUR stack pointer) so that we may resart the FPU. *
- \***************************************************************/
- stcr TMP, SSBR /* done with SSBR, TMP now free */
- RESTORE_TMP2 /* done with extra temp regs */
- RESTORE_TMP3 /* done with extra temp regs */
-
- /* Get the current PSR and modify for the rte to enable the FPU */
- ldcr TMP, PSR
- clr TMP, TMP, 1<PSR_FPU_DISABLE_BIT> /* enable the FPU */
- clr TMP, TMP, 1<PSR_SHADOW_FREEZE_BIT> /* also enable shadowing */
- stcr TMP, EPSR
-
- /* the "+2" below is to set the VALID_BIT */
- or.u TMP, r0, hi16(fpu_enable + 2)
- or TMP, TMP, lo16(fpu_enable + 2)
- stcr TMP, SNIP /* jump to here fpu_enable */
- addu TMP, TMP, 4
- stcr TMP, SFIP /* and then continue after that */
-
- set FLAGS, FLAGS, 1<FLAG_ENABLING_FPU> /* note what we're doing.*/
- xcr FLAGS, FLAGS, SR1
- st r1, r31, REG_OFF(EF_RET) /* save the return address */
- ld r1, r31, GENREG_OFF(1) /* get original r1 */
-
- xcr TMP, r31, SR3 /* TMP now restored. R31 now saved in SR3 */
- ld r31, r31, GENREG_OFF(31) /* get original r31 */
-
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: CPU flags *
- * SR2: free *
- * SR3: pointer to our exception frame (our stack pointer) *
- * r1 through r31: original exception-time values *
- * *
- * Valid in the exception frame: *
- * Exception-time FLAGS. *
- * Exception-time espr, sfip, snip, sxip. *
- * Exception number (EF_VECTOR). *
- * Dmt0 *
- * Other data pipeline control registers, if appropriate. *
- * FPU control registers, if appropriate. *
- * Exception SR3, if appropriate. *
- * Held temporarly in the exception frame: *
- * Return address to the calling excption handler. *
- *************************************************** *
- * immediate goal: *
- * Do an RTE to restart the fpu and jump to "fpu_enable" *
- * Another exception (or exceptions) may be raised in *
- * this, which is why FLAG_ENABLING_FPU is set in SR1. *
- \***************************************************************/
- RTE /* jumps to "fpu_enable" on the next line to enable the FPU. */
-
- _LABEL(fpu_enable)
- FLUSH_PIPELINE
- xcr TMP, TMP, SR3 /* get E.F. pointer */
- st.d r30, TMP, GENREG_OFF(30) /* save previous r30, r31 */
- or r31, TMP, r0 /* transfer E.F. pointer to r31 */
- ld TMP, r31, REG_OFF(EF_SR3)/* get previous SR3; maybe important*/
-
- /* make sure that the FLAG_ENABLING_FPU bit is off */
- xcr FLAGS, FLAGS, SR1
- clr FLAGS, FLAGS, 1<FLAG_ENABLING_FPU>
- xcr FLAGS, FLAGS, SR1
-
- xcr TMP, TMP, SR3 /* replace TMP, SR3 */
-
- /* now save all regs to the exception frame. */
- st.d r0 , r31, GENREG_OFF(0)
- st.d r2 , r31, GENREG_OFF(2)
- st.d r4 , r31, GENREG_OFF(4)
- st.d r6 , r31, GENREG_OFF(6)
- st.d r8 , r31, GENREG_OFF(8)
- st.d r10, r31, GENREG_OFF(10)
- st.d r12, r31, GENREG_OFF(12)
- st.d r14, r31, GENREG_OFF(14)
- st.d r16, r31, GENREG_OFF(16)
- st.d r18, r31, GENREG_OFF(18)
- st.d r20, r31, GENREG_OFF(20)
- st.d r22, r31, GENREG_OFF(22)
- st.d r24, r31, GENREG_OFF(24)
- st.d r26, r31, GENREG_OFF(26)
- st.d r28, r31, GENREG_OFF(28)
-#ifdef JEFF_DEBUG
- /* mark beginning of frame with notable value */
- or.u r20, r0, hi16(0x12345678)
- or r20, r20, lo16(0x12345678)
- st r20, r31, GENREG_OFF(0)
-#endif
-
- /***************** REGISTER STATUS BLOCK ***********************\
- * SR0: current thread *
- * SR1: free *
- * SR2: free *
- * SR3: previous exception-time SR3 *
- * r1: return address to the calling exception handler *
- * r2 through r30: free *
- * r31: our exception frame *
- * *
- * Valid in the exception frame: *
- * Exception-time r0 through r31. *
- * Exception-time FLAGS. *
- * Exception-time espr, sfip, snip, sxip. *
- * Exception number (EF_VECTOR). *
- * Dmt0 *
- * Other data pipeline control registers, if appropriate. *
- * FPU control registers, if appropriate. *
- * Exception SR3, if appropriate. *
- *************************************************** *
- * immediate goal: *
- * Pick up a stack if we came in from user mode. Put *
- * A copy of the exception frame pointer into r30 *
- * bump the stack a doubleword and write the exception *
- * frame pointer. *
- * if not an interrupt exception, *
- * Turn on interrupts and service any outstanding *
- * data access exceptions. *
- * Return to calling exception handler to *
- * service the exception. *
- \***************************************************************/
-
- /*
- * If it's not the interrupt exception, enable interrupts and
- * take care of any data access exceptions......
- *
- * If interrupt exception, switch to interrupt stack if not
- * already there. Else, switch to kernel stack.
- */
- or r30, r0, r31 /* get a copy of the e.f. pointer */
- ld r2, r31, REG_OFF(EF_EPSR)
- bb1 PSR_SUPERVISOR_MODE_BIT, r2, 1f /* If in kernel mode */
-
- ld r3, r31, REG_OFF(EF_VECTOR)
- cmp r3, r3, 1 /* is interrupt ? */
- bb0 eq, r3, 2f
- or.u r31, r0, hi16(_intstack_end) /* swith to int stack */
- or r31, r31, lo16(_intstack_end)
- br 3f
- 2:
- or.u r31, r0, hi16(_kstack)
- ld r31, r31, lo16(_kstack)
- addu r31, r31, USIZE /* point at proper end */
- br 3f
- 1:
- ld r3, r31, REG_OFF(EF_VECTOR)
- cmp r3, r3, 1 /* is interrupt ? */
- bb0 eq, r3, 3f /* no, we will stay on kern stack */
- or.u r31, r0, hi16(_intstack_end) /* swith to int stack */
- or r31, r31, lo16(_intstack_end)
- /* This label is here for debugging */
- exception_handler_has_ksp: global exception_handler_has_ksp
- 3: /*
- here - r30 holds a pointer to the exception frame.
- r31 is a pointer to the kernel stack/interrupt stack.
- */
- subu r31, r31, 8 /* make some breathing space */
- st r30, r31, 0 /* store frame pointer on the stack */
-#if DDB
- st r30, r31, 4 /* store it again for the debugger to recognize */
-#endif DDB
-
- ld r2, r30, REG_OFF(EF_VECTOR)
- bcnd.n eq0, r2, return_to_calling_exception_handler /* is error */
- ld r14, r30, REG_OFF(EF_RET)
- cmp r3, r2, 1 /* interrupt is exception #1 ;Is an interrupt? */
- bb1.n eq, r3, return_to_calling_exception_handler /* skip if so */
-
-#if DDB
- cmp r3, r2, 130 /* DDB break exception */
- bb1.n eq, r3, return_to_calling_exception_handler
-
- cmp r3, r2, 132 /* DDB entry exception */
- bb1.n eq, r3, return_to_calling_exception_handler
-#endif
-
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT> /* enable interrupts */
- stcr r2, PSR
-#if DDB
- FLUSH_PIPELINE
-#endif
-
- /* service any outstanding data pipeline stuff
- - check dmt0 anything outstanding?*/
-
- ld r3, r30, REG_OFF(EF_DMT0)
- bb0 DMT_VALID_BIT, r3, return_to_calling_exception_handler
-
-/*
- r30 can be clobbered by calls. So stuff its value into a
- preserved register, say r15. R14 is in use (see return_to_... below).
- */
- or r15, r0, r30
-
- CALL(_trap, T_DATAFLT, r15)
- CALL(_data_access_emulation, r15, r0)
-
-/* restore it... */
- or r30, r0, r15
-
- /* clear the dmt0 word in the E.F */
- st r0, r30, REG_OFF(EF_DMT0)
-
- _LABEL(return_to_calling_exception_handler)
- jmp r14 /* loaded above */
-
-
-
-/*
- * ##########################################################################
- * ##########################################################################
- * ##########################################################################
- */
-
-LABEL(return_from_exception_handler)
-LABEL(_return_from_main)
- /*
- * Regs r1-r30 are free. R31 is pointing at the word
- * on the kernel stack where our pointer to the exception frame
- * it stored. Reload it now.
- *
- * At this point, if EF_DMT0 is not zero, then
- * this must have been an interrupt where the fault didn't
- * get corrected above. We'll do that now.
- *
- * We load it into r14 since it is preserved across function
- * calls, and we may have to call some routines from within here.
- *
- * control is transfered here from obvious places in this file
- * and thread_bootstrap in luna88k/locore.c.
- *
- */
-#define FPTR r14
- ld FPTR, r31, 0 /* grab exception frame pointer */
- ld r3, FPTR, REG_OFF(EF_DMT0)
- bb0 DMT_VALID_BIT, r3, _check_ast /*[Oh well, nothing to do here] */
-
-#if 1
- /*
- * This might happen for non-interrupts If the user sets DMT0
- * in an exception handler.........
- */
- ld r2, FPTR, REG_OFF(EF_VECTOR)
- cmp r2, r2, 1 /* interrupt is exception #1 ; Is an interrupt? */
- bb1 eq, r2, 1f
- LABEL(oops)
- or.u r4, r0, hi16(2f)
- or r4, r4, lo16(2f)
-#if DDB
- CALL(_db_printf, r4, r0)
- tb0 0, r0, 132
-#endif
- br 1f
- data
- 2: string "OOPS: DMT0 not zero and not interrupt.\n\000"
- align 4
- text
- 1:
-#endif
- /*
- * If it's the interrupt exception, enable interrupt.
- * Take care of any data access exception...... 90/8/15 add by yama
- */
- ld r2, FPTR, REG_OFF(EF_VECTOR)
- cmp r2, r2, 1 /* interrupt is exception #1 ; Is an interrupt? */
- bb1 ne, r2, 1f /* If not so, skip */
-
- /* if EPSR has interrupts disabled, skip also */
- ld r2, FPTR, REG_OFF(EF_EPSR)
- bb1 PSR_INTERRUPT_DISABLE_BIT, r2, 1f /* skip if disabled */
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT> /* enable interrupts */
- FLUSH_PIPELINE
- stcr r2, PSR
- 1:
- ld r2, FPTR, REG_OFF(EF_DMT0)
- bb0 DMT_VALID_BIT, r2, 2f
-
- /*
- * if there happens to be a data fault that hasn't been serviced yet,
- * go off and service that...
- */
- CALL(_trap, T_DATAFLT, r30)
- CALL(_data_access_emulation, r30, r0) /* really only 2 args */
-
- /* clear the dmt0 word in the E.F. */
- st r0 , FPTR, REG_OFF(EF_DMT0)
- 2:
-
-LABEL(_check_ast)
-
- ldcr r1, PSR /* get current PSR */
- set r1, r1, 1<PSR_INTERRUPT_DISABLE_BIT> /* set for disable intr. */
- stcr r1, PSR /* install new PSR */
- FLUSH_PIPELINE
-
- /*
- *
- * This code (including a bit above) is more or less:
- *
- * check_ast:
- *
- * Disable interrupts
- * if (exception was from user mode && want_ast)
- * {
- * trap(AST, frame)
- * goto check_ast
- * }
- *
- * We want to service AST's only if returning to user space.
- */
-
- ld r2, FPTR, REG_OFF(EF_EPSR) /* get pre-exception PSR */
- bb1 PSR_SUPERVISOR_MODE_BIT, r2, no_ast /*skip if in system mode */
-
- /* get and check want_ast */
- or.u r2, r0, hi16(_want_ast)
- ld r3, r2, lo16(_want_ast)
- bcnd eq0, r3, no_ast
- /*
- * trap(AST,...) will service
- * software interrupts and
- * network interrupts
- */
- CALL(_trap, T_ASTFLT, FPTR) /* enter with interrupts disabled */
- subu r31, r31, 40 /* return with interrupts enabled */
- addu r31, r31, 40
- br _check_ast /* and check again..... */
-
-_LABEL(no_ast)
-
- /* now ready to return....*/
-
- /*
- * Transfer the frame pointer to r31, since we no longer need a stack.
- * No page faults here, and interrupts are disabled.
- */
-
- or r31, r0, FPTR
-
-
-/* restore r1 later */
- ld.d r2 , r31, GENREG_OFF(2)
- ld.d r4 , r31, GENREG_OFF(4)
- ld.d r6 , r31, GENREG_OFF(6)
- ld.d r8 , r31, GENREG_OFF(8)
- ld.d r10, r31, GENREG_OFF(10)
- ld.d r12, r31, GENREG_OFF(12)
- ld.d r14, r31, GENREG_OFF(14)
- ld.d r16, r31, GENREG_OFF(16)
- ld.d r18, r31, GENREG_OFF(18)
- ld.d r20, r31, GENREG_OFF(20)
- ld.d r22, r31, GENREG_OFF(22)
- ld.d r24, r31, GENREG_OFF(24)
- ld.d r26, r31, GENREG_OFF(26)
- ld.d r28, r31, GENREG_OFF(28)
- /* restore r1, r30, r31 later */
-
-
- /* disable shadowing (interrupts already disabled above) */
- ldcr r1, PSR
- set r1, r1, 1<PSR_SHADOW_FREEZE_BIT>
- FLUSH_PIPELINE
- stcr r1, PSR
-
- /* 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 r30, r31, REG_OFF(EF_SNIP)
- ld r1, r31, REG_OFF(EF_SFIP)
- stcr r0, SSBR
- stcr r30, SNIP
- stcr r1, SFIP
-
- ld r30, r31, REG_OFF(EF_EPSR)
- ld r1, r31, REG_OFF(EF_MODE)
- stcr r30, EPSR
-
- /* Now restore r1, r30, and r31 */
- ld r1, r31, GENREG_OFF(1)
- ld.d r30, r31, GENREG_OFF(30)
-
- _LABEL(return_from_exception)
- RTE
-
-/***********************************************************************/
-/***********************************************************************/
-/***********************************************************************/
diff --git a/sys/arch/mvme88k/m88k/exception_return.s b/sys/arch/mvme88k/m88k/exception_return.s
deleted file mode 100644
index 9c79a5ba083..00000000000
--- a/sys/arch/mvme88k/m88k/exception_return.s
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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 10:54:27 deraadt
- * Initial revision
- *
- * 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/m88k/genassym.c b/sys/arch/mvme88k/m88k/genassym.c
deleted file mode 100644
index 3511defe6c3..00000000000
--- a/sys/arch/mvme88k/m88k/genassym.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 1982, 1990 The 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.
- *
- * @(#)genassym.c 7.8 (Berkeley) 5/7/91
- * $Id: genassym.c,v 1.1 1995/10/18 10:54:25 deraadt Exp $
- */
-
-#ifndef KERNEL
-#define KERNEL
-#endif /* KERNEL */
-
-#include <sys/param.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mbuf.h>
-#include <sys/msgbuf.h>
-#include <machine/cpu.h>
-#include <machine/trap.h>
-#include <machine/psl.h>
-#include <machine/vmparam.h>
-#include <sys/syscall.h>
-#include <vm/vm.h>
-#include <sys/user.h>
-
-#define pair(TOKEN, ELEMENT) \
- printf("#define " TOKEN " %u\n", (unsigned)(ELEMENT))
-
-#define int_offset_of_element(ELEMENT) (((unsigned)&(ELEMENT))/sizeof(int))
-
-main()
-{
- register struct proc *p = (struct proc *)0;
- struct m88100_saved_state *ss = (struct m88100_saved_state *) 0;
- register struct vmmeter *vm = (struct vmmeter *)0;
- register struct user *up = (struct user *)0;
- register struct rusage *rup = (struct rusage *)0;
- struct vmspace *vms = (struct vmspace *)0;
- pmap_t pmap = (pmap_t)0;
- struct pcb *pcb = (struct pcb *)0;
- register unsigned i;
-
- printf("#ifndef __GENASSYM_INCLUDED\n");
- printf("#define __GENASSYM_INCLUDED 1\n\n");
-
- printf("#ifdef ASSEMBLER\n"
- "#define NEWLINE \\\\ \n"
- "#endif\n");
-
- printf("#define\tP_FORW %d\n", &p->p_forw);
- printf("#define\tP_BACK %d\n", &p->p_back);
- printf("#define\tP_VMSPACE %d\n", &p->p_vmspace);
- printf("#define\tP_ADDR %d\n", &p->p_addr);
- printf("#define\tP_PRIORITY %d\n", &p->p_priority);
- printf("#define\tP_STAT %d\n", &p->p_stat);
- printf("#define\tP_WCHAN %d\n", &p->p_wchan);
- printf("#define\tSRUN %d\n", SRUN);
-
- printf("#define\tVM_PMAP %d\n", &vms->vm_pmap);
- printf("#define\tV_INTR %d\n", &vm->v_intr);
-
- printf("#define\tUPAGES %d\n", UPAGES);
- printf("#define\tPGSHIFT %d\n", PGSHIFT);
-
- printf("#define\tU_PROF %d\n", &up->u_stats.p_prof);
- printf("#define\tU_PROFSCALE %d\n", &up->u_stats.p_prof.pr_scale);
- printf("#define\tPCB_ONFAULT %d\n", &pcb->pcb_onfault);
- printf("#define\tSIZEOF_PCB %d\n", sizeof(struct pcb));
-
- printf("#define\tSYS_exit %d\n", SYS_exit);
- printf("#define\tSYS_execve %d\n", SYS_execve);
- printf("#define\tSYS_sigreturn %d\n", SYS_sigreturn);
-
- pair("EF_R0", int_offset_of_element(ss->r[0]));
- pair("EF_R31", int_offset_of_element(ss->r[31]));
- pair("EF_FPSR", int_offset_of_element(ss->fpsr));
- pair("EF_FPCR", int_offset_of_element(ss->fpcr));
- pair("EF_EPSR", int_offset_of_element(ss->epsr));
- pair("EF_SXIP", int_offset_of_element(ss->sxip));
- pair("EF_SFIP", int_offset_of_element(ss->sfip));
- pair("EF_SNIP", int_offset_of_element(ss->snip));
- pair("EF_SSBR", int_offset_of_element(ss->ssbr));
- pair("EF_DMT0", int_offset_of_element(ss->dmt0));
- pair("EF_DMD0", int_offset_of_element(ss->dmd0));
- pair("EF_DMA0", int_offset_of_element(ss->dma0));
- pair("EF_DMT1", int_offset_of_element(ss->dmt1));
- pair("EF_DMD1", int_offset_of_element(ss->dmd1));
- pair("EF_DMA1", int_offset_of_element(ss->dma1));
- pair("EF_DMT2", int_offset_of_element(ss->dmt2));
- pair("EF_DMD2", int_offset_of_element(ss->dmd2));
- pair("EF_DMA2", int_offset_of_element(ss->dma2));
- pair("EF_FPECR", int_offset_of_element(ss->fpecr));
- pair("EF_FPHS1", int_offset_of_element(ss->fphs1));
- pair("EF_FPLS1", int_offset_of_element(ss->fpls1));
- pair("EF_FPHS2", int_offset_of_element(ss->fphs2));
- pair("EF_FPLS2", int_offset_of_element(ss->fpls2));
- pair("EF_FPPT", int_offset_of_element(ss->fppt));
- pair("EF_FPRH", int_offset_of_element(ss->fprh));
- pair("EF_FPRL", int_offset_of_element(ss->fprl));
- pair("EF_FPIT", int_offset_of_element(ss->fpit));
- pair("EF_VECTOR", int_offset_of_element(ss->vector));
- pair("EF_MASK", int_offset_of_element(ss->mask));
- pair("EF_MODE", int_offset_of_element(ss->mode));
-
- pair("EF_RET", int_offset_of_element(ss->scratch1));
- pair("EF_NREGS", sizeof(*ss)/sizeof(int));
-
- /* make a sanity check */
- if (sizeof(*ss) & 7)
- {
- /*
- * This contortion using write instead of fputs(stderr)
- * is necessary because we can't include stdio.h in here.
- */
- static char buf[] =
- "Exception frame not a multiple of double words\n";
- write(2 /* stderr */,buf,sizeof(buf));
- exit(1);
- }
- pair("SIZEOF_EF", sizeof(*ss));
- printf("\n#endif /* __GENASSYM_INCLUDED */\n");
- exit(0);
-}
diff --git a/sys/arch/mvme88k/m88k/locore.S b/sys/arch/mvme88k/m88k/locore.S
deleted file mode 100644
index e0c2ad9c862..00000000000
--- a/sys/arch/mvme88k/m88k/locore.S
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * 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.
- */
-
-/* $RCSfile: locore.S,v $ -- asm boot routines
- *
- **********************************************************************
- *****************************************************************RCS**/
-
-#ifndef ASSEMBLER /* predefined by ascpp, at least */
-#define ASSEMBLER
-#endif
-
-#include "machine/locore.h"
-#include "machine/m88100.h"
-#include "machine/trap.h"
-#include "machine/asm.h"
-#include "machine/board.h" /* lots of stuff (OBIO_PIO*, SYSV_BASE, etc)*/
-#include "machine/vmparam.h" /* INTSTACK_SIZE */
-#include "assym.s"
-
-/***********************************************************************/
-
-/*
- * Arrange for the include file version number to appear directly in
- * the namelist.
- */
-global _INCLUDE_VERSION
-def _INCLUDE_VERSION, INCLUDE_VERSION
-#ifndef NBPG
-#define NBPG 4096
-#endif /* NBPG */
-
-#ifndef UADDR
-#define UADDR 0xFFEE0000 /* address of u */
-#endif /* UADDR */
-#ifndef USIZE
-#define USIZE (UPAGES * NBPG)
-#endif /* USIZE */
-/*
- * The memory looks like:
- * 0x00000 - 0x01000 : trap vectors
- * 0x01000 - 0x10000 : first 64k used by BUG
- * 0x10000 == start : Boot loader jumps here. (for now, this can
- * handle only NMAGIC - screwy linker)
- *
- ***********************************************************************/
- text
-
-LABEL(_kernelstart)
-LABEL(_start)
-LABEL(start)
- br _start_text
-#if 0
- .align 4096 ; VBR points to page aligned list
- _LABEL(vector_list) /* references memory BELOW this line */
- #include "machine/exception_vectors.h"
- word END_OF_VECTOR_LIST
-
- _LABEL(_msgsw)
- word 0 /* Bits here turn on/off debugging somewhere. */
-#endif
-/*
- * Do a dump. Called by auto-restart.
- */
-
- global _dumpsys
-LABEL(_doadump)
- bsr _dumpsys
- bsr _doboot
- /*NOTREACHED*/
-
-/**************************************************************************/
-LABEL(_start_text) /* This is the *real* start upon poweron or reset */
- /*
- * Args passed by boot loader
- * r2 howto
- * r3 first_addr (first available address)
- * r4 ((Clun << 8) | Dlun & FF) -> bootdev
- * r5 esym
- * r6 miniroot
- */
- or.u r13, r0, hi16(_boothowto)
- st r2, r13, lo16(_boothowto)
- or.u r13, r0, hi16(_first_addr)
- st r3, r13, lo16(_first_addr)
-#if 0
- or.u r13, r0, hi16(_bootdev)
- st r4, r13, lo16(_bootdev)
-#endif
- or.u r13, r0, hi16(_esym)
- st r5, r13, lo16(_esym)
- or.u r13, r0, hi16(_miniroot)
- st r6, r13, lo16(_miniroot)
-
- /*
- * CPU Initialization
- *
- * Every CPU starts from here..
- * (well, from 'start' above, which just jumps here).
- *
- * I use r11 and r22 here 'cause they're easy to not
- * get mixed up -- r10, for example, looks too similar
- * to r0 when not being careful....
- *
- * Ensure that the PSR is as we like:
- * supervisor mode
- * big-endian byte ordering
- * concurrent operation allowed
- * carry bit clear (I don't think we really care about this)
- * FPU enabled
- * misaligned access raises an exception
- * interrupts disabled
- * shadow registers frozen
- *
- * The manual says not to disable interrupts and freeze shadowing
- * at the same time because interupts are not actually disabled
- * until after the next instruction. Well, if an interrupt
- * occurs now, we're in deep anyway, so I'm going to do
- * the two together.
- *
- * Upon a reset (or poweron, I guess), the PSR indicates:
- * supervisor mode
- * interrupts, shadowing, FPU, missaligned exception: all disabled
- *
- * We'll just construct our own turning on what we want.
- *
- * jfriedl@omron.co.jp
- */
- stcr r0, SSBR /* clear this for later */
-
- /* XXX We can use SR0-SR3 for any purpose */
- set r11, r0, 1<PSR_SUPERVISOR_MODE_BIT>
- set r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r11, PSR
- /* shadowing, FPU, misalgined access exception: all enabled now.*/
-#if 0
- or.u r11, r0, hi16(_vector_list)
- or r11, r11, lo16(_vector_list)
- stcr r11, VBR
-#endif /* 0 */
- stcr r0, VBR
-
-/************************************************************************/
-
-#if defined(RAW_PRINTF) && RAW_PRINTF
- bsr replace_mayput_with_rawputchar
-#endif
-
- /*
- * switch to interrupt stack
- */
- or.u r31, r0, hi16(_intstack_end)
- or r31, r31, lo16(_intstack_end)
- clr r31, r31, 3<0> /* round down to 8-byte boundary */
-
- /*
- * Want to make the call:
- * vector_init(VBR, vector_list)
- */
- or.u r3, r0, hi16(_vector_list)
- or r3, r3, lo16(_vector_list)
- bsr.n _vector_init
- ldcr r2, VBR
-
-#if 0
- /* clear BSS. Boot loader might have already done this... */
- or.u r2, r0, hi16(_edata)
- or r2, r2, lo16(_edata)
- or.u r4, r0, hi16(_end)
- or r4, r4, lo16(_end)
- bsr.n _bzero /* bzero(edata, end-edata) */
- subu r3, r4, r2
-#endif
-
- /* still on int stack */
- bsr.n _m187_bootstrap
- subu r31, r31, 40
- addu r31, r31, 40
-
- /* switch to proc0 uarea */
-
- or.u r10, r0, hi16(UADDR)
- or r31, r10,lo16(UADDR)
- addu r31, r31, USIZE
-
- /* make the call: main() */
- bsr.n _main
- subu r31, r31, 40
- addu r31, r31, 40
- br _return_from_main
-
-/*****************************************************************************/
-
- data
- .align 4096 ; VBR points to page aligned list
- global _vector_list
-_vector_list: ; references memory BELOW this line
- #include "machine/exception_vectors.h"
- word END_OF_VECTOR_LIST
-
- global _msgsw
-_msgsw:
- word 0 ;Bits here turn on/off debugging somewhere.
- .align 4096
- global _intstack
- global _intstack_end
-_intstack:
- space 4 * NBPG /* 16K */
-_intstack_end:
-
-/*
- * When a process exits and its u. area goes away, we set curpcb to point
- * to this `u.', leaving us with something to use for an interrupt stack,
- * and letting all the register save code have a pcb_uw to examine.
- * This is also carefully arranged (to come just before u0, so that
- * process 0's kernel stack can quietly overrun into it during bootup, if
- * we feel like doing that).
- * Should be page aligned.
- */
- global _idle_u
-_idle_u:
- space UPAGES * NBPG
-
-/*
- * Process 0's u.
- *
- * This must be page aligned
- */
- global _u0
- align 4096
-_u0: space UPAGES * NBPG
-estack0:
-
-/*
- * UPAGES get mapped to kstack
- */
-
- global _kstack
-_kstack:
- word UADDR
-
-#ifdef DDB
- global _esym
-_esym:
- word 0
-#endif /* DDB */
-
- global _proc0paddr /* move to C code */
-_proc0paddr:
- word _u0 /* KVA of proc0 uarea */
-
-/*
- * _curpcb points to the current pcb (and hence u. area).
- * Initially this is the special one.
- */
-/*
- * pcb is composed of kernel state + user state
- * I may have to change curpcb to u0 + PCB_USER based on what
- * other parts expect XXX
- */
- global _curpcb /* move to C code */
-_curpcb: word _u0 /* curpcb = &u0 */
-
-/*
- * Trampoline code. Gets copied to the top of
- * user stack in exec.
- */
- global _sigcode
-_sigcode:
- /* r31 points to sigframe */
- ld r2, r31, 0 /* signo */
- ld r3, r31, 4 /* code */
- ld r4, r31, 8 /* sigcontext* */
- or r5, r0, 0 /* addr = 0 for now */
- ld r6, r31, 12 /* handler */
- jsr.n r6
- addu r31, r31, 40
- subu r31, r31, 40
- ld r2, r31, 8 /* sigcontext* */
- or r9, r0, SYS_sigreturn
- tb0 0, r0, 128 /* syscall trap, calling sigreturn */
- or r0, r0, 0
- or r0, r0, 0
- /* sigreturn will not return unless it fails */
- or r9, r0, SYS_exit
- tb0 0, r0, 128 /* syscall trap, exit */
- or r0, r0, 0
- or r0, r0, 0
- global _esigcode
-_esigcode:
-
-#if 0
-/*
- * thread_bootstrap:
- *
- * Bootstrap a new thread using the thread state that has been
- * placed on the stack. Our fp has been set up for us, we only need
- * to fix up a few things in the saved frame, then get into
- * usermode.
- */
-ENTRY(thread_bootstrap)
- /*
- * Here r31 should point to the place on our stack which
- * contains a pointer to our exception frame.
- */
-#if DDB
- ENTRY_ASM
-#endif
- br return_from_exception_handler
-
-/*
- * save_context
- */
-ENTRY(save_context)
- subu r31,r31,40 /* allocate stack for r1 and args */
- st r1,r31,36 /* save return address */
- bsr _spl /* get the current interrupt mask */
- ld r1,r31,36 /* recover return address */
- addu r31,r31,40 /* put stack pointer back */
- ldcr r10,SR0 /* r10 <- current_thread() */
- ld r10,r10,THREAD_PCB /* r10 <- pcb */
-#if (PCB_KERNEL!=0)
- addu r10, r10, PCB_KERNEL /* point to kernel save region */
-#endif
- st r1,r10,0 /* do setjmp */ /* save return address */
- st r14,r10,4
- st r15,r10,2*4
- st r16,r10,3*4
- st r17,r10,4*4
- st r18,r10,5*4
- st r19,r10,6*4
- st r20,r10,7*4
- st r21,r10,8*4
- st r22,r10,9*4
- st r23,r10,10*4
- st r24,r10,11*4
- st r25,r10,12*4
- /* In principle, registers 26-29 are never manipulated in the
- kernel. Maybe we can skip saving them? */
- st r26,r10,13*4
- st r27,r10,14*4
- st r28,r10,15*4
- st r29,r10,16*4
- st r30,r10,17*4 /* save frame pointer */
- st r31,r10,18*4 /* save stack pointer */
- st r2,r10,19*4 /* save interrupt mask */
- /* we need to switch to the interrupt stack here */
- or.u r31, r0, hi16(_intstack)
- or r31, r31, lo16(_intstack)
- addu r31, r31, INTSTACK_SIZE /* end of stack */
- clr r31, r31, 3<0> /* round down to 8-byte boundary */
- jmp.n r1
- or r2,r0,r0
-#endif /* 0 */
-
-/* ------------------------------------------------------------------------ */
-/*
- * unsigned measure_pause(volatile int *flag)
- *
- * Count cycles executed until *flag becomes nonzero.
- * Return the number of cycles counted.
- */
-ENTRY(measure_pause)
- /* R2 is pointer to flag */
- def GRANULAIRTY, 10000
-
- or r3, r0, 1 /* r3 is my counter, this is the first */
-
- measure_pause_outer_loop:
- or r4, r0, GRANULAIRTY
-
- measure_pause_inner_loop:
- /*
- * Execute a tight loop of a known number of cycles.
- * This assumes, of course, that the instruction cache is on.
- * This loop takes two cycles per iteration.
- */
- bcnd.n ne0, r4, measure_pause_inner_loop
- subu r4, r4, 1
-
-
- /*
- * Now add the number of cycles done above (plus the overhead
- * of the outer loop) to the total count.
- * Also, check the *flag and exit the outer loop if it's non-zero.
- *
- * The overhead is really unknown because it's not known how
- * the memory system will tread the access to *flag, so we just
- * take a guess.
- */
- ld r4, r2, r0 /* get the flag */
- addu r3, r3, (GRANULAIRTY * 2 + 10) /* account for the cost */
- bcnd eq0, r4, measure_pause_outer_loop /* continue or exit the loop*/
-
- jmp.n r1
- or r2, r3, r0 /* pass count back */
-
-/*
- * void delay_in_microseconds(int count)
- *
- * The processor loops (busy waits) for the given number of microseconds:
- * Thus, delay_in_microseconds(1000000) will delay for one second.
- *
- * REGISTER USAGE:
- * IN r1 - return address
- * IN r2 - (signed int) number of microseconds
- * r3 - (float) number of microseconds
- * r4/5 - (double) number of cycles per microsecond
- * r6 - (float) number of cycles to delay
- * r7 - (signed) number of cycles to delay
- */
-ENTRY(delay_in_microseconds)
-ENTRY(delay)
- flt.ss r3, r2 /* convert microseconds from signed int to float */
- or.u r4, r0, hi16(_cycles_per_microsecond)
- ld.d r4, r4, lo16(_cycles_per_microsecond)
- fmul.ssd r6, r3, r4 /* convert microseconds to cycles */
- int.ss r7, r6 /* convert cycles from float to signed int */
- subu r7, r7, 25 /* subtract for overhead of above instruction */
-
- /* now loop for the given number of cycles */
- pause_loop:
- bcnd.n gt0, r7, pause_loop
- subu r7, r7, 2 /* two cycles per iteration */
-
- jmp r1 /* return */
-
-#if 0
-/*
- * void switch_to_shutdown_context(thread_t thread,
- * void (*routine)(processor_t),
- * processor_t processor)
- *
- * saves the kernel context of the thread,
- * switches to the interrupt stack,
- * continues the thread (with thread_dispatch),
- * then runs routine on the interrupt stack.
- *
- */
-
-ENTRY(switch_to_shutdown_context)
-/* call save_context to save the thread state */
- subu r31, r31, 40
- or r25, r3, r0 /* save arguments */
- or r24, r4, r0
- bsr.n _save_context
- st r1, r31, 36
- addu r31, r31, 40
- ldcr r10, SR0 /* r10 <- current_thread() */
- st r31, r10, THREAD_KERNEL_STACK /* save stack pointer */
- st r0, r10, THREAD_SWAP_FUNC /* null continuation */
- ldcr r11, SR1
- mak r11, r11, FLAG_CPU_FIELD_WIDTH<0> /* r1 = cpu # */
- or r12, r12, lo16(_interrupt_stack)
- ld r31, r12 [r11]
- addu r31, r31, INTSTACK_SIZE /* end of stack */
- clr r31, r31, 3<0> /* round down to 8-byte boundary */
- /* save the thread; switched to the interrupt stack; now call thread
- dispatch to get rid of this thread */
- or r2, r10, r0
- bsr.n _thread_dispatch
- subu r31, r31, 40
- /* call the continuation routine */
- jsr.n r25
- or r2, r24, r0
- /* panic if here */
- or.u r2, r0, hi16(1f)
- bsr.n _panic
- or r2, r2, lo16(1f)
-1:
- string "switch_to_shutdown_context"
-#endif /* 0 */
diff --git a/sys/arch/mvme88k/m88k/locore2.c b/sys/arch/mvme88k/m88k/locore2.c
deleted file mode 100644
index e8e6a57e86f..00000000000
--- a/sys/arch/mvme88k/m88k/locore2.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 10:54:27 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/m88k/locore_asm_routines.S b/sys/arch/mvme88k/m88k/locore_asm_routines.S
deleted file mode 100644
index 73ac642a3d3..00000000000
--- a/sys/arch/mvme88k/m88k/locore_asm_routines.S
+++ /dev/null
@@ -1,1668 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1992 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.
- */
-/* locore_asm_routines.c
- *
- **********************************************************************
- * This file created by Omron Corporation, 1990.
- *
- * HISTORY
- *
- **************************************************************RCS*****/
-
-#ifndef ASSEMBLER
-# define ASSEMBLER
-#endif
-
-#include <machine/asm.h>
-#include <machine/locore.h>
-#include <machine/trap.h>
-#include <machine/board.h>
-#include <sys/errno.h>
-
-
-#undef ENTRY /* don't want anything to do with a G?PROF ENTRY() */
-#ifdef __STDC__
-# define ENTRY(name) align 4 NEWLINE _ ## name: global _ ## name
-#else
-# define ENTRY(name) align 4 NEWLINE _/**/name: global _/**/name
-#endif
-
-
-/*****************************************************************************
- * DO_LOAD_ADDRESS
- *
- * unsigned int do_load_word(address, supervisor_mode)
- * vm_offset_t address; \\ in r2
- * boolean_t supervisor_mode; \\ in r3
- *
- * Return the word at ADDRESS (from user space if SUPERVISOR_MODE is zero,
- * supervisor space if non-zero).
- *
- */
-
-ENTRY(do_load_word) /* do_load_word(address, supervisor) */
- bcnd ne0,r3,1f
-#if ERRATA__XXX_USR
- NOP
- ld.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.usr r2,r2,r0
-#endif
- br 2f
-1: ld r2,r2,r0
-2: jmp r1
-
-ENTRY(do_load_half) /* do_load_half(address, supervisor) */
- bcnd ne0,r3,1f
-#if ERRATA__XXX_USR
- NOP
- ld.h.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.h.usr r2,r2,r0
-#endif
- br 2f
-1: ld.h r2,r2,r0
-2: jmp r1
-
-ENTRY(do_load_byte) /* do_load_byte(address, supervisor) */
- bcnd ne0,r3,1f
-#if ERRATA__XXX_USR
- NOP
- ld.b.usr r2,r2,r0
- NOP
- NOP
- NOP
-#else
- ld.b.usr r2,r2,r0
-#endif
- br 2f
-1: ld.b r2,r2,r0
-2: jmp r1
-
-ENTRY(do_store_word) /* do_store_word(address, data, supervisor) */
- bcnd ne0,r4,1f
-#if ERRATA__XXX_USR
- NOP
- st.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.usr r3,r2,r0
-#endif
- br 2f
-1: st r3,r2,r0
-2: jmp r1
-
-ENTRY(do_store_half) /* do_store_half(address, data, supervisor) */
- bcnd ne0,r4,1f
-#if ERRATA__XXX_USR
- NOP
- st.h.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r3,r2,r0
-#endif
- br 2f
-1: st.h r3,r2,r0
-2: jmp r1
-
-ENTRY(do_store_byte) /* do_store_byte(address, data, supervisor) */
- bcnd ne0,r4,1f
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- st.b.usr r3,r2,r0
-#endif
- br 2f
-1: st.b r3,r2,r0
-2: jmp r1
-
-ENTRY(do_xmem_word) /* do_xmem_word(address, data, supervisor) */
- bcnd ne0,r4,1f
-#if ERRATA__XXX_USR
- NOP
- xmem.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- xmem.usr r3,r2,r0
-#endif
- br 2f
-1: xmem r3,r2,r0
-2: jmp r1
-
-ENTRY(do_xmem_byte) /* do_xmem_byte(address, data, supervisor) */
- bcnd ne0,r4,1f
-#if ERRATA__XXX_USR
- NOP
- xmem.bu.usr r3,r2,r0
- NOP
- NOP
- NOP
-#else
- xmem.bu.usr r3,r2,r0
-#endif
- br 2f
-1: xmem.bu r3,r2,r0
-2: jmp r1
-
-/*************************************************************************
- *************************************************************************
- **
- ** void enable_interrupt(void)
- **
- ** Enables processor interrupts (for the executing cpu).
- **/
-#undef enable_interrupt
-ENTRY(enable_interrupt)
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
- jmp r1
-
-#if DDB
-/* a version of enable_interrupt for the debugger; should never
- have breakpoints set it in. Keep it consistent with enable
- interrupt above */
-ENTRY(db_enable_interrupt)
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
- jmp r1
-#endif /* DDB */
-
-/*************************************************************************
- *************************************************************************
- **
- ** unsigned long disable_interrupt(void)
- **
- ** Disables processor interrupts (for the executing CPU) and returns
- ** the *previous* PSR.
- **
- ** if ((oldPSR & 0x02) == 0)
- ** interrupts_were_previously_on = 1;
- **/
-#undef disable_interrupt
-ENTRY(disable_interrupt)
- ldcr r2, PSR
- set r3, r2, 1<PSR_INTERRUPT_DISABLE_BIT> /* set disable bit*/
- stcr r3, PSR
- FLUSH_PIPELINE
- jmp r1
-
-/* a version of disable_interrupt for the kernel debugger. Should never
- have breakpoints set in it. Make sure it stays consistent with
- disable_interrupt */
-
-#if DDB
-ENTRY(db_disable_interrupt)
- ldcr r2, PSR
- set r3, r2, 1<PSR_INTERRUPT_DISABLE_BIT> /* set disable bit*/
- stcr r3, PSR
- FLUSH_PIPELINE
- jmp r1
-#endif /* DDB */
-
-/* version for the debugger */
-
-#if DDB
-
-ENTRY(db_are_interrupts_disabled)
- ldcr r2, PSR /* get the processor status word */
- set r3, r0, 1<PSR_INTERRUPT_DISABLE_BIT> /* set mask */
- jmp.n r1 /* delayed return */
- and r2, r2, r3 /* r2 = r3 & r2 */
-#endif /* DDB */
-
-LABEL(_FAULT_ERROR)
- or r2,r0,1 /* bad copy */
- jmp r1
-
-;LABEL(_ALLOW_FAULT_START)
-
-/*
- * Fetch from user space
- * r2 == address in user space
- */
-
-ENTRY(fuword)
-ENTRY(fuiword)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- ld.usr r5, r0, r2
- NOP
- NOP
- NOP
-#else
- ld.usr r5, r0, r2
-#endif
- or r2, r0, r5
- br fusu_ret
-fusu_fault:
- subu r2, r0, 1
-fusu_ret:
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- st r0, r6, PCB_ONFAULT ; pcb_onfault = 0
-
- jmp r1
-
-ENTRY(fusword)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- ld.h.usr r5, r0, r2
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, r0, r2
-#endif
- or r2, r0, r5
- br fusu_ret
-
-ENTRY(fubyte)
-ENTRY(fuibyte)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- ld.b.usr r5, r0, r2
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, r0, r2
-#endif
- or r2, r0, r5
- br fusu_ret
-
-ENTRY(fuswintr)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(_fubail)
- or r5, r5, lo16(_fubail)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fubail
-#if ERRATA__XXX_USR
- NOP
- ld.h.usr r5, r2, r0
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, r2, r0
-#endif
- or r2, r0, r5
- br fusu_ret
-
-ENTRY(fubail)
- subu r2, r0, 1
- br fusu_ret
-
-/*
- * store to user space.
- * r2 == address in user space
- * r3 == byte/short/word
- */
-
-ENTRY(suword)
-ENTRY(suiword)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- st.usr r3, r2, r0
- NOP
- NOP
- NOP
-#else
- st.usr r3, r2, r0
-#endif
- or r2, r0, r0 /* return success */
- br fusu_ret
-
-ENTRY(susword)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- st.h.usr r3, r2, r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r3, r2, r0
-#endif
- or r2, r0, r0 /* return success */
- br fusu_ret
-
-ENTRY(subyte)
-ENTRY(suibyte)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(fusu_fault)
- or r5, r5, lo16(fusu_fault)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = fusu_fault
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r3, r2, r0
- NOP
- NOP
- NOP
-#else
- st.b.usr r3, r2, r0
-#endif
- or r2, r0, r0 /* return success */
- br fusu_ret
-
-ENTRY(suswintr)
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(_subail)
- or r5, r5, lo16(_subail)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = subail
-#if ERRATA__XXX_USR
- NOP
- st.h.usr r3, r2, r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r3, r2, r0
-#endif
- or r2, r0, r0 /* return success */
- br fusu_ret
-
-ENTRY(subail)
- subu r2, r0, 1
- br fusu_ret
-
-#if 0
-/*
- * copystr(fromaddr, toaddr, maxlength, &lencopied)
- *
- * Copy a null terminated string from one point to another in
- * the kernel address space.
- * NOTE: maxlength must be < 64K
- */
-ENTRY(copystr)
- movl sp@(4),a0 | a0 = fromaddr
- movl sp@(8),a1 | a1 = toaddr
- moveq #0,d0
- movw sp@(14),d0 | d0 = maxlength
- jlt Lcsflt1 | negative count, error
- jeq Lcsdone | zero count, all done
- subql #1,d0 | set up for dbeq
-Lcsloop:
- movb a0@+,a1@+ | copy a byte
- dbeq d0,Lcsloop | if !null and more, continue
- jne Lcsflt2 | ran out of room, error
- moveq #0,d0 | got a null, all done
-Lcsdone:
- tstl sp@(16) | return length desired?
- jeq Lcsret | no, just return
- subl sp@(4),a0 | determine how much was copied
- movl sp@(16),a1 | return location
- movl a0,a1@ | stash it
-Lcsret:
- rts
-Lcsflt1:
- moveq #EFAULT,d0 | copy fault
- jra Lcsdone
-Lcsflt2:
- moveq #ENAMETOOLONG,d0 | ran out of space
- jra Lcsdone
-
-#endif /* 0 */
- jmp r1
-/*
- * Copy specified amount of data from user space into the kernel
- * copyin(from, to, len)
- * r2 == from (user source address)
- * r3 == to (kernel destination address)
- * r4 == length
- * (r1=return addr)
- */
-
-#define SRC r2
-#define DEST r3
-#define LEN r4
-
-ENTRY(copyin)
- /* set up fault handler */
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(.Lciflt)
- or r5, r5, lo16(.Lciflt)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = .Lciflt
-
- ;bcnd ne0, LEN, 1f ; XXX optimize len = 0 case
- ;or r2, r0, 0
- ;br .Lcidone
- ;1: ;bcnd lt0, LEN, .Lciflt ; EFAULT if len < 0
-
- /* If it's a small length (less than 8), then do byte-by-byte */
- cmp r9, LEN, 8
- bb1 lt, r9, copyin_byte_only
-
- /* If they're not aligned similiarly, use byte only... */
- xor r9, SRC, DEST
- mask r8, r9, 0x3
- bcnd ne0, r8, copyin_byte_only
-
- /*
- * At this point, we don't know if they're word aligned or not,
- * but we know that what needs to be done to one to align
- * it is what's needed for the other.
- */
- bb1 0, SRC, copyin_left_align_to_halfword
-copyin_left_aligned_to_halfword:
- bb1 1, SRC, copyin_left_align_to_word
-copyin_left_aligned_to_word:
- bb1 0, LEN, copyin_right_align_to_halfword
-copyin_right_aligned_to_halfword:
- bb1 1, LEN, copyin_right_align_to_word
-copyin_right_aligned_to_word:
-
- /* At this point, both SRC and DEST are aligned to a word */
- /* boundry, and LEN is an even multiple of 4. */
- bb1.n 2, LEN, copyin_right_align_to_doubleword
- or r7, r0, 4
-
-copyin_right_aligned_to_doubleword:
-#if ERRATA__XXX_USR
- NOP
- ld.usr r5, SRC, r0
- NOP
- NOP
- NOP
- ld.usr r6, SRC, r7
- NOP
- NOP
- NOP
-#else
- ld.usr r5, SRC, r0
- ld.usr r6, SRC, r7
-#endif
- subu LEN, LEN, 8
- st r5, DEST, r0
- addu SRC, SRC, 8
- st r6, DEST, r7
- bcnd.n ne0, LEN, copyin_right_aligned_to_doubleword
- addu DEST, DEST, 8
- or r2, r0, r0 /* successful return */
- br .Lcidone
-
- /***************************************************/
-
-copyin_left_align_to_halfword:
-#if ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, r0
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, r0
-#endif
- subu LEN, LEN, 1
- st.b r5, DEST, r0
- addu SRC, SRC, 1
- br.n copyin_left_aligned_to_halfword
- addu DEST, DEST, 1
-
-copyin_left_align_to_word:
-#if ERRATA__XXX_USR
- NOP
- ld.h.usr r5, SRC, r0
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, SRC, r0
-#endif
- subu LEN, LEN, 2
- st.h r5, DEST, r0
- addu SRC, SRC, 2
- br.n copyin_left_aligned_to_word
- addu DEST, DEST, 2
-
-copyin_right_align_to_halfword:
- subu LEN, LEN, 1
-#if ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, LEN
-#endif
- br.n copyin_right_aligned_to_halfword
- st.b r5, DEST, LEN
-
-copyin_right_align_to_word:
- subu LEN, LEN, 2
-#if ERRATA__XXX_USR
- NOP
- ld.h.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.h.usr r5, SRC, LEN
-#endif
- br.n copyin_right_aligned_to_word
- st.h r5, DEST, LEN
-
-copyin_right_align_to_doubleword:
- subu LEN, LEN, 4
-#if ERRATA__XXX_USR
- NOP
- ld.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.usr r5, SRC, LEN
-#endif
- bcnd.n ne0, LEN, copyin_right_aligned_to_doubleword
- st r5, DEST, LEN
- or r2, r0, r0 /* successful return */
- br .Lcidone
-
-copyin_byte_only:
- bcnd eq0, LEN, 2f
- 1:
- subu LEN, LEN, 1
-#if ERRATA__XXX_USR
- NOP
- ld.b.usr r5, SRC, LEN
- NOP
- NOP
- NOP
-#else
- ld.b.usr r5, SRC, LEN
-#endif
- bcnd.n ne0, LEN, 1b
- st.b r5, DEST, LEN
- 2: or r2, r0, r0 /* successful return */
- br .Lcidone
-.Lcidone:
- or.u r5,r0,hi16(_curpcb)
- ld r6,r5,lo16(_curpcb)
- st r0,r6,PCB_ONFAULT
- jmp r1
-.Lciflt:
- or r2, r0, EFAULT /* return fault */
- br .Lcidone
-
-#undef SRC
-#undef DEST
-#undef LEN
-/*######################################################################*/
-/*######################################################################*/
-
-/*
- * Copy a null terminated string from the user space to the kernel
- * address space.
- *
- * copyinstr(from, to, maxlen, &lencopied)
- * r2 == from
- * r3 == to
- * r4 == maxlen
- * r5 == len actually transferred
- * r6 & r7 - used as temporaries
- */
-#define SRC r2
-#define DEST r3
-#define CNT r4
-#define LEN r5
-
-ENTRY(copyinstr)
- /* setup fault handler */
- or.u r6, r0, hi16(_curpcb)
- ld r7, r6, lo16(_curpcb)
- or.u r6, r0, hi16(.Lcisflt)
- or r6, r6, lo16(.Lcisflt)
- st r6, r7, PCB_ONFAULT
- bcnd lt0, CNT, .Lcisflt
- bcnd eq0, CNT, .Lcisdone
- or r6, r0, 0
- 1:
-#if ERRATA__XXX_USR
- NOP
- ld.bu.usr r7, SRC, r6
- NOP
- NOP
- NOP
-#else
- ld.bu.usr r7, SRC, r6
-#endif
- st.b r7, DEST, r6
- bcnd eq0, r7, 2f ; all done
- addu r6, r6, 1
- cmp r7, r6, CNT
- bb1 lt, r7, 1b
- or r2, r0, ENAMETOOLONG ; over flow
- br .Lcisdone
- 2: ; all done
- or r2, r0, 0
- br .Lcisdone
-
-.Lcisdone:
- bcnd eq0, LEN, 3f
- st r6, r0, LEN
- 3: or.u r5,r0,hi16(_curpcb)
- ld r6,r5,lo16(_curpcb)
- st r0,r6,PCB_ONFAULT /* clear the handler */
- jmp r1
-.Lcisflt:
- or r2, r0, EFAULT /* return fault */
- br .Lcisdone
-
-#undef SRC
-#undef DEST
-#undef CNT
-#undef LEN
-
-/*
- * Copy specified amount of data from kernel to the user space
- * Copyout(from, to, len)
- * r2 == from (kernel source address)
- * r3 == to (user destination address)
- * r4 == length
- */
-
-#define SRC r2
-#define DEST r3
-#define LEN r4
-
-ENTRY(copyout)
- /* setup fault handler */
- or.u r5, r0, hi16(_curpcb)
- ld r6, r5, lo16(_curpcb)
- or.u r5, r0, hi16(.Lcoflt)
- or r5, r5, lo16(.Lcoflt)
- st r5, r6, PCB_ONFAULT ; pcb_onfault = .Lcoflt
- ;bcnd ne0, LEN, 1f ; XXX optimize len = 0 case
- ;or r2, r0, 0
- ;br .Lcodone
- ;1: ;bcnd lt0, LEN, .Lcoflt ; EFAULT if len < 0
- /* If it's a small length (less than 8), then do byte-by-byte */
- cmp r9, LEN, 8
- bb1 lt, r9, copyout_byte_only
-
- /* If they're not aligned similiarly, use byte only... */
- xor r9, SRC, DEST
- mask r8, r9, 0x3
- bcnd ne0, r8, copyout_byte_only
-
- /*
- * At this point, we don't know if they're word aligned or not,
- * but we know that what needs to be done to one to align
- * it is what's needed for the other.
- */
- bb1 0, SRC, copyout_left_align_to_halfword
-copyout_left_aligned_to_halfword:
- bb1 1, SRC, copyout_left_align_to_word
-copyout_left_aligned_to_word:
- bb1 0, LEN, copyout_right_align_to_halfword
-copyout_right_aligned_to_halfword:
- bb1 1, LEN, copyout_right_align_to_word
-copyout_right_aligned_to_word:
-
- /*
- * At this point, both SRC and DEST are aligned to a word
- * boundry, and LEN is an even multiple of 4.
- */
- bb1.n 2, LEN, copyout_right_align_to_doubleword
- or r7, r0, 4
-
-copyout_right_aligned_to_doubleword:
- ld r5, SRC, r0
- ld r6, SRC, r7
- subu LEN, LEN, 8
-#if ERRATA__XXX_USR
- NOP
- st.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 8
-#if ERRATA__XXX_USR
- NOP
- st.usr r6, DEST, r7
- NOP
- NOP
- NOP
-#else
- st.usr r6, DEST, r7
-#endif
- bcnd.n ne0, LEN, copyout_right_aligned_to_doubleword
- addu DEST, DEST, 8
- or r2, r0, r0 /* successful return */
- br .Lcodone
-
- /***************************************************/
-copyout_left_align_to_halfword:
- ld.b r5, SRC, r0
- subu LEN, LEN, 1
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.b.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 1
- br.n copyout_left_aligned_to_halfword
- addu DEST, DEST, 1
-
-copyout_left_align_to_word:
- ld.h r5, SRC, r0
- subu LEN, LEN, 2
-#if ERRATA__XXX_USR
- NOP
- st.h.usr r5, DEST, r0
- NOP
- NOP
- NOP
-#else
- st.h.usr r5, DEST, r0
-#endif
- addu SRC, SRC, 2
- br.n copyout_left_aligned_to_word
- addu DEST, DEST, 2
-
-copyout_right_align_to_halfword:
- subu LEN, LEN, 1
- ld.b r5, SRC, LEN
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- br copyout_right_aligned_to_halfword
-#else
- br.n copyout_right_aligned_to_halfword
- st.b.usr r5, DEST, LEN
-#endif
-
-copyout_right_align_to_word:
- subu LEN, LEN, 2
- ld.h r5, SRC, LEN
-#if ERRATA__XXX_USR
- NOP
- st.h.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- br copyout_right_aligned_to_word
-#else
- br.n copyout_right_aligned_to_word
- st.h.usr r5, DEST, LEN
-#endif
-
-copyout_right_align_to_doubleword:
- subu LEN, LEN, 4
- ld r5, SRC, LEN
-#if ERRATA__XXX_USR
- NOP
- st.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- bcnd ne0, LEN, copyout_right_aligned_to_doubleword
-#else
- bcnd.n ne0, LEN, copyout_right_aligned_to_doubleword
- st.usr r5, DEST, LEN
-#endif
- or r2, r0, r0 /* successful return */
- br .Lcodone
-
-_LABEL(copyout_byte_only)
- bcnd eq0, LEN, 2f
- 1:
- subu LEN, LEN, 1
- ld.b r5, SRC, LEN
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r5, DEST, LEN
- NOP
- NOP
- NOP
- bcnd ne0, LEN, 1b
-# else
- bcnd.n ne0, LEN, 1b
- st.b.usr r5, DEST, LEN
-# endif
-
- 2: or r2, r0, r0 /* successful return */
- br .Lcodone
-
-.Lcodone:
- or.u r5,r0,hi16(_curpcb)
- ld r6,r5,lo16(_curpcb)
- st r0,r6,PCB_ONFAULT /* clear the handler */
- jmp r1
-.Lcoflt:
- or r2, r0, EFAULT /* return fault */
- br .Lcodone
-
-#undef SRC
-#undef DEST
-#undef LEN
-
-/*
- * Copy a null terminated string from the kernel space to the user
- * address space.
- *
- * copyoutstr(from, to, maxlen, &lencopied)
- * r2 == from
- * r3 == to
- * r4 == maxlen that can be copied
- * r5 == len actually copied
- */
-
-#define SRC r2
-#define DEST r3
-#define CNT r4
-#define LEN r5
-
-ENTRY(copyoutstr)
- /* setup fault handler */
- or.u r6, r0, hi16(_curpcb)
- ld r7, r6, lo16(_curpcb)
- or.u r6, r0, hi16(.Lcosflt)
- or r6, r6, lo16(.Lcosflt)
- st r6, r7, PCB_ONFAULT
- bcnd lt0, CNT, .Lcosflt
- bcnd eq0, CNT, .Lcosdone
- or r6, r0, 0
- 1:
- ld.bu r7, SRC, r6
-#if ERRATA__XXX_USR
- NOP
- st.b.usr r7, DEST, r6
- NOP
- NOP
- NOP
-#else
- st.b.usr r7, DEST, r6
-#endif
- bcnd eq0, r7, 2f ; all done
- addu r6, r6, 1
- cmp r7, r6, CNT
- bb1 lt, r7, 1b
- or r2, r0, ENAMETOOLONG ; over flow
- br .Lcosdone
- 2: ; all done
- or r2, r0, 0
- br .Lcosdone
-
-.Lcosflt:
- or r2, r0, EFAULT /* return fault */
- br .Lcosdone
-
-.Lcosdone:
- bcnd eq0, LEN, 3f
- st r6, r0, LEN
- 3: or.u r5,r0,hi16(_curpcb)
- ld r6,r5,lo16(_curpcb)
- st r0,r6,PCB_ONFAULT /* clear the handler */
- jmp r1
-
-#undef SRC
-#undef DEST
-#undef CNT
-#undef LEN
-
-/*######################################################################*/
-;LABEL(_ALLOW_FAULT_END)
-;word 0 /* to separate from routine below */
-/*######################################################################*/
-
-/*
- * Gcc 2 generates calls to memcpy for bcopies of unknown size. memcpy
- * can simply be implemented as ovbcopy but the src (r2, r3) and dst args need to
- * be switched.
- */
-/*
- * void memcpy(dest, source, count)
- *
- */
-ENTRY(memcpy)
- or r5, r0, r2 /* dst -> tmp */
- or r2, r0, r3 /* src -> 1st arg */
- br.n _ovbcopy /* call ovbcopy */
- or r3, r0, r5 /* dst -> 2nd arg */
-
-
-/*
- * void bcopy(source, destination, count)
- *
- * copy count bytes of data from source to destination
- * Don Harper (don@omron.co.jp), Omron Corporation.
- *
- */
-
-ENTRY(bcopy)
-ENTRY(ovbcopy)
- bcnd le0,r4,bcopy_out /* nothing to do if count <= 0 */
-/*
- * check position of source and destination data
- */
- cmp r9,r2,r3 /* compare source address to destination */
- bb1 eq,r9,bcopy_out /* nothing to do if addresses are equal */
- bb1 lo,r9,bcopy_reverse /* copy in reverse if src < destination */
-/*
- * source address is greater than destination address, copy forward
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,f_byte_copy /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(f_strat) /* forward strategy table address (high) */
- or r12,r12,lo16(f_strat) /* forward strategy table address (low) */
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-_LABEL(f_3byte_word_copy)
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- addu r2,r2,3 /* increment source pointer */
- addu r3,r3,3 /* increment destination pointer */
- br.n f_word_copy /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-_LABEL(f_1half_word_copy)
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- addu r2,r2,2 /* increment source pointer */
- addu r3,r3,2 /* increment destination pointer */
- br.n f_word_copy /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-_LABEL(f_1byte_word_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-_LABEL(f_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,f_byte_copy /* not enough left, copy bytes */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n f_word_copy /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-_LABEL(f_1byte_half_copy)
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-_LABEL(f_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,f_byte_copy /* not enough left, copy bytes */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- addu r2,r2,16 /* increment source pointer */
- addu r3,r3,16 /* increment destination pointer */
- br.n f_half_copy /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-_LABEL(f_byte_copy)
- bcnd eq0,r4,bcopy_out /* branch if nothing left to copy */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- addu r2,r2,1 /* increment source pointer */
- addu r3,r3,1 /* increment destination pointer */
- br.n f_byte_copy /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-/*
- * source address is less than destination address, copy in reverse
- */
-_LABEL(bcopy_reverse)
-/*
- * start copy pointers at end of data
- */
- addu r2,r2,r4 /* start source at end of data */
- addu r3,r3,r4 /* start destination at end of data */
-/*
- * check for short data
- */
- cmp r9,r4,16 /* see if we have at least 16 bytes */
- bb1 lt,r9,r_byte_copy /* copy bytes for small data length */
-/*
- * determine copy strategy based on alignment of source and destination
- */
- mask r6,r2,3 /* get 2 low order bits of source address */
- mask r7,r3,3 /* get 2 low order bits of destintation addr */
- mak r6,r6,0<4> /* convert source bits to table offset */
- mak r7,r7,0<2> /* convert destination bits to table offset */
- or.u r12,r0,hi16(r_strat) /* reverse strategy table address (high) */
- or r12,r12,lo16(r_strat) /* reverse strategy table address (low) */
- addu r6,r6,r7 /* compute final table offset for strategy */
- ld r12,r12,r6 /* load the strategy routine */
- jmp r12 /* branch to strategy routine */
-
-/*
- * Copy three bytes from src to destination then copy words
- */
-_LABEL(r_3byte_word_copy)
- subu r2,r2,3 /* decrement source pointer */
- subu r3,r3,3 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- ld.bu r7,r2,1 /* load byte from source */
- ld.bu r8,r2,2 /* load byte from source */
- st.b r6,r3,0 /* store byte to destination */
- st.b r7,r3,1 /* store byte to destination */
- st.b r8,r3,2 /* store byte to destination */
- br.n r_word_copy /* copy full words */
- subu r4,r4,3 /* decrement length */
-
-/*
- * Copy 1 halfword from src to destination then copy words
- */
-_LABEL(r_1half_word_copy)
- subu r2,r2,2 /* decrement source pointer */
- subu r3,r3,2 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load half-word from source */
- st.h r6,r3,0 /* store half-word to destination */
- br.n r_word_copy /* copy full words */
- subu r4,r4,2 /* decrement remaining length */
-
-/*
- * Copy 1 byte from src to destination then copy words
- */
-_LABEL(r_1byte_word_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to word copy */
-/*
- * Copy as many full words as possible, 4 words per loop
- */
-_LABEL(r_word_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,r_byte_copy /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld r6,r2,0 /* load first word */
- ld r7,r2,4 /* load second word */
- ld r8,r2,8 /* load third word */
- ld r9,r2,12 /* load fourth word */
- st r6,r3,0 /* store first word */
- st r7,r3,4 /* store second word */
- st r8,r3,8 /* store third word */
- st r9,r3,12 /* store fourth word */
- br.n r_word_copy /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-_LABEL(r_1byte_half_copy)
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load 1 byte from source */
- st.b r6,r3,0 /* store 1 byte to destination */
- subu r4,r4,1 /* decrement remaining length */
- /* fall through to half copy */
-
-_LABEL(r_half_copy)
- cmp r10,r4,16 /* see if we have 16 bytes remaining */
- bb1 lo,r10,r_byte_copy /* not enough left, copy bytes */
- subu r2,r2,16 /* decrement source pointer */
- subu r3,r3,16 /* decrement destination pointer */
- ld.hu r6,r2,0 /* load first half-word */
- ld.hu r7,r2,2 /* load second half-word */
- ld.hu r8,r2,4 /* load third half-word */
- ld.hu r9,r2,6 /* load fourth half-word */
- ld.hu r10,r2,8 /* load fifth half-word */
- ld.hu r11,r2,10 /* load sixth half-word */
- ld.hu r12,r2,12 /* load seventh half-word */
- ld.hu r13,r2,14 /* load eighth half-word */
- st.h r6,r3,0 /* store first half-word */
- st.h r7,r3,2 /* store second half-word */
- st.h r8,r3,4 /* store third half-word */
- st.h r9,r3,6 /* store fourth half-word */
- st.h r10,r3,8 /* store fifth half-word */
- st.h r11,r3,10 /* store sixth half-word */
- st.h r12,r3,12 /* store seventh half-word */
- st.h r13,r3,14 /* store eighth half-word */
- br.n r_half_copy /* branch to copy another block */
- subu r4,r4,16 /* decrement remaining length */
-
-_LABEL(r_byte_copy)
- bcnd eq0,r4,bcopy_out /* branch if nothing left to copy */
- subu r2,r2,1 /* decrement source pointer */
- subu r3,r3,1 /* decrement destination pointer */
- ld.bu r6,r2,0 /* load byte from source */
- st.b r6,r3,0 /* store byte in destination */
- br.n r_byte_copy /* branch for next byte */
- subu r4,r4,1 /* decrement remaining length */
-
-_LABEL(bcopy_out)
- jmp r1 /* all done, return to caller */
-
- data
- align 4
-_LABEL(f_strat)
- word f_word_copy
- word f_byte_copy
- word f_half_copy
- word f_byte_copy
- word f_byte_copy
- word f_3byte_word_copy
- word f_byte_copy
- word f_1byte_half_copy
- word f_half_copy
- word f_byte_copy
- word f_1half_word_copy
- word f_byte_copy
- word f_byte_copy
- word f_1byte_half_copy
- word f_byte_copy
- word f_1byte_word_copy
-
-_LABEL(r_strat)
- word r_word_copy
- word r_byte_copy
- word r_half_copy
- word r_byte_copy
- word r_byte_copy
- word r_1byte_word_copy
- word r_byte_copy
- word r_1byte_half_copy
- word r_half_copy
- word r_byte_copy
- word r_1half_word_copy
- word r_byte_copy
- word r_byte_copy
- word r_1byte_half_copy
- word r_byte_copy
- word r_3byte_word_copy
-
- text
-
-/*######################################################################*/
-/*######################################################################*/
-
-/*
- * April 1990, Omron Corporation
- * jfriedl@nff.ncl.omron.co.jp
- *
- * void bzero(destination, length)
- *
- * Clear (set to zero) LENGTH bytes of memory starting at DESTINATION.
- * Note that there is no return value.
- *
- * This is fast. Really fast. Especially for long lengths.
- */
-#define R_dest r2
-#define R_len r3
-
-#define R_bytes r4
-#define R_mark_address r5
-#define R_addr r6 /* R_addr && R_temp SHARE */
-#define R_temp r6 /* R_addr && R_temp SHARE */
-
-
-ENTRY(blkclr)
-ENTRY(bzero)
- /*
- * If the destination is not word aligned, we'll word align
- * it first to make things easier.
- *
- * We'll check to see first if bit #0 is set and then bit #1
- * (of the destination address). If either are set, it's
- * not word aligned.
- */
- bb1 0, R_dest, not_initially_word_aligned
- bb1 1, R_dest, not_initially_word_aligned
-
- now_word_aligned:
- /*
- * before we get into the main loop, grab the
- * address of the label "mark" below.
- */
- or.u R_mark_address, r0, hi16(mark)
- or R_mark_address, R_mark_address, lo16(mark)
-
- top_of_main_loop:
-# define MAX_AT_ONE_TIME 128
- /*
- * Now we find out how many words we can zero-fill in a row.
- * We do this by doing something like:
- *
- * bytes &= 0xfffffffc;
- * if (bytes > MAX_AT_ONE_TIME)
- * bytes = MAX_AT_ONE_TIME;
- */
-
- /*
- * Clear lower two bits of length to give us the number of bytes
- * ALIGNED TO THE WORD LENGTH remaining to move.
- */
- clr R_bytes, R_len, 2<0>
-
- /* if we're done clearing WORDS, jump out */
- bcnd eq0, R_bytes, done_doing_words
-
- /* if the number of bytes > MAX_AT_ONE_TIME, do only the max */
- cmp R_temp, R_bytes, MAX_AT_ONE_TIME
- bb1 lt, R_temp, 1f
-
- /*
- * Since we're doing the max, we know exactly where we're
- * jumping (the first one in the list!), so we can jump
- * right there. However, we've still got to adjust
- * the length, so we'll jump to where we ajust the length
- * which just happens to fall through to the first store zero
- * in the list.
- *
- * Note, however, that we're jumping to an instruction that
- * would be in the delay slot for the jump in front of it,
- * so if you change things here, WATCH OUT.
- */
- br.n do_max
- or R_bytes, r0, MAX_AT_ONE_TIME
-
- 1:
-
- /*
- * Now we have the number of bytes to zero during this iteration,
- * (which, as it happens, is the last iteration if we're here).
- * We'll calculate the proper place to jump and then jump there,
- * after adjusting the length. NOTE that there is a label between
- * the "jmp.n" and the "subu" below... the "subu" is NOT always
- * executed in the delay slot of the "jmp.n".
- */
- subu R_addr, R_mark_address, R_bytes
-
- /* and go there (after adjusting the length via ".n") */
- jmp.n R_addr
-do_max: subu R_len, R_len, R_bytes /* NOTE: this is in the delay slot! */
-
- st r0, R_dest, 0x7c /* 128 */
- st r0, R_dest, 0x78 /* 124 */
- st r0, R_dest, 0x74 /* 120 */
- st r0, R_dest, 0x70 /* 116 */
- st r0, R_dest, 0x6c /* 112 */
- st r0, R_dest, 0x68 /* 108 */
- st r0, R_dest, 0x64 /* 104 */
- st r0, R_dest, 0x60 /* 100 */
- st r0, R_dest, 0x5c /* 96 */
- st r0, R_dest, 0x58 /* 92 */
- st r0, R_dest, 0x54 /* 88 */
- st r0, R_dest, 0x50 /* 84 */
- st r0, R_dest, 0x4c /* 80 */
- st r0, R_dest, 0x48 /* 76 */
- st r0, R_dest, 0x44 /* 72 */
- st r0, R_dest, 0x40 /* 68 */
- st r0, R_dest, 0x3c /* 64 */
- st r0, R_dest, 0x38 /* 60 */
- st r0, R_dest, 0x34 /* 56 */
- st r0, R_dest, 0x30 /* 52 */
- st r0, R_dest, 0x2c /* 44 */
- st r0, R_dest, 0x28 /* 40 */
- st r0, R_dest, 0x24 /* 36 */
- st r0, R_dest, 0x20 /* 32 */
- st r0, R_dest, 0x1c /* 28 */
- st r0, R_dest, 0x18 /* 24 */
- st r0, R_dest, 0x14 /* 20 */
- st r0, R_dest, 0x10 /* 16 */
- st r0, R_dest, 0x0c /* 12 */
- st r0, R_dest, 0x08 /* 8 */
- st r0, R_dest, 0x04 /* 4 */
- st r0, R_dest, 0x00 /* 0 */
-
- mark:
- br.n top_of_main_loop
- addu R_dest, R_dest, R_bytes /* bump up the dest address */
-
-
-
- done_doing_words:
- bcnd ne0, R_len, finish_up_last_bytes
- jmp r1 /* RETURN */
-
- finish_up_last_bytes:
- subu R_len, R_len, 1
- bcnd.n ne0, R_len, finish_up_last_bytes
- st.b r0, R_dest, R_len
-
- leave:
- jmp r1 /* RETURN */
-
- not_initially_word_aligned:
- /*
- * Bzero to word-align the address (at least if the length allows it).
- */
- bcnd eq0, R_len, leave
- st.b r0, R_dest, 0
- addu R_dest, R_dest, 1
- mask R_temp, R_dest, 0x3
- bcnd.n eq0, R_temp, now_word_aligned
- subu R_len, R_len, 1
- br not_initially_word_aligned
-
-#undef R_dest
-#undef R_len
-#undef R_bytes
-#undef R_mark_address
-#undef R_addr
-#undef R_temp
-#undef MAX_AT_ONE_TIME
-
-/**********************************************************************/
-/**********************************************************************/
-/**********************************************************************/
-
-/*
- * non-local goto
- */
- global _setjmp
-_setjmp:
- st r1,r2,0
- st r14,r2,4
- st r15,r2,2*4
- st r16,r2,3*4
- st r17,r2,4*4
- st r18,r2,5*4
- st r19,r2,6*4
- st r20,r2,7*4
- st r21,r2,8*4
- st r22,r2,9*4
- st r23,r2,10*4
- st r24,r2,11*4
- st r25,r2,12*4
- st r26,r2,13*4
- st r27,r2,14*4
- st r28,r2,15*4
- st r29,r2,16*4
- st r30,r2,17*4
- st r31,r2,18*4
- jmp.n r1
- or r2,r0,r0
-
- global _longjmp
-_longjmp:
- ld r1,r2,0
- ld r14,r2,4
- ld r15,r2,2*4
- ld r16,r2,3*4
- ld r17,r2,4*4
- ld r18,r2,5*4
- ld r19,r2,6*4
- ld r20,r2,7*4
- ld r21,r2,8*4
- ld r22,r2,9*4
- ld r23,r2,10*4
- ld r24,r2,11*4
- ld r25,r2,12*4
- ld r26,r2,13*4
- ld r27,r2,14*4
- ld r28,r2,15*4
- ld r29,r2,16*4
- ld r30,r2,17*4
- ld r31,r2,18*4
- jmp.n r1
- or r2,r3,r0
-
-ENTRY(longjmp_int_enable)
- ld r1,r2,0
- ld r14,r2,4
- ld r15,r2,2*4
- ld r16,r2,3*4
- ld r17,r2,4*4
- ld r18,r2,5*4
- ld r19,r2,6*4
- ld r20,r2,7*4
- ld r21,r2,8*4
- ld r22,r2,9*4
- ld r23,r2,10*4
- ld r24,r2,11*4
- ld r25,r2,12*4
- ld r26,r2,13*4
- ld r27,r2,14*4
- ld r28,r2,15*4
- ld r29,r2,16*4
- ld r30,r2,17*4
- ld r31,r2,18*4
- or r2,r3,r0
- ldcr r10,PSR
- clr r10,r10,1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10,PSR
- jmp r1
-
-ENTRY(getsp)
- or r2, r0, r31
- jmp r1
-
-ENTRY(spln)
- ldcr r10,PSR
- or r11,r0,r10
- set r10,r10,1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10,PSR
- or.u r3,r0,hi16(INT_MASK_LEVEL)
- or r4,r3,lo16(INT_MASK_LEVEL)
- xmem.bu r2,r4,r0
- stcr r11,PSR
- FLUSH_PIPELINE
- jmp r1
-
-ENTRY(spl)
- ldcr r10,PSR
- or r11,r0,r10
- set r10,r10,1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10,PSR
- or.u r3,r0,hi16(INT_MASK_LEVEL)
- ld.b r2,r3,lo16(INT_MASK_LEVEL)
- stcr r11,PSR
- FLUSH_PIPELINE
- jmp r1
-
-/*
- * 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.
- */
-ENTRY(invalidate_pte)
- or r3,r0,r0
- xmem r3,r2,r0
- tb1 0,r0,0
- jmp.n r1
- or r2,r3,r0
-
-#if DDB
-
-ENTRY(db_spln)
- ldcr r10,PSR
- or r11,r0,r10
- set r10,r10,1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10,PSR
- or.u r3,r0,hi16(INT_MASK_LEVEL)
- or r4,r3,lo16(INT_MASK_LEVEL)
- xmem.bu r2,r4,r0
- stcr r11,PSR
- FLUSH_PIPELINE
- jmp r1
-
-ENTRY(db_spl)
- ldcr r10,PSR
- or r11,r0,r10
- set r10,r10,1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r10,PSR
- or.u r3,r0,hi16(INT_MASK_LEVEL)
- ld.b r2,r3,lo16(INT_MASK_LEVEL)
- stcr r11,PSR
- FLUSH_PIPELINE
- jmp r1
-
-ENTRY(db_flush_pipeline)
- FLUSH_PIPELINE
- jmp r1
-#endif /* DDB */
-
-ENTRY(read_processor_identification_register)
- jmp.n r1
- ldcr r2, PID
-
-#if 0
-/*
- * call rom abort (called when non-maskable interrupt detected)
- */
-ENTRY(call_rom_abort)
- tcnd eq0, r0, EVN_ROM_ABORT /* trap to ROM */
- jmp r1 /* and return */
-
-#endif /* 0 */
-;------------------------------------------------------------------------
-
-#ifdef JUNK
-/* JEFF_DEBUG stuff */
- align 8
-raw_xpr_stack_top:
- zero 0x40
-raw_xpr_inital_stack_frame:
- zero 0x60
-raw_xpr_stack_bottom:
-
-user_raw_xpr: global user_raw_xpr
- ldcr r5, cr17
- ld r5, r5, THREAD_TASK
- /* get a stack ... can use r9 no problem */
- or.u r9, r0, hi16(raw_xpr_inital_stack_frame)
- or r9, r9, lo16(raw_xpr_inital_stack_frame)
- st r31, r9, 0x38
- st r1, r9, 0x3c
- or r31, r9, r0
- bsr __raw_xpr
- ld r1, r31, 0x3c
- ld r31, r31, 0x38
- rte
-;--------------------------------------------------------------
-_raw_xpr: global _raw_xpr
- or.u r5, r0, hi16(_kernel_task)
- ld r5, r5, lo16(_kernel_task)
- br __raw_xpr
-#endif /* JUNK */
diff --git a/sys/arch/mvme88k/m88k/locore_c_routines.c b/sys/arch/mvme88k/m88k/locore_c_routines.c
deleted file mode 100644
index 4f07bee8506..00000000000
--- a/sys/arch/mvme88k/m88k/locore_c_routines.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * 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
- *****************************************************************RCS**/
-/* This file created by Omron Corporation, 1990. */
-
-#include <machine/m88100.h> /* DMT_VALID */
-#include <assym.s> /* EF_NREGS, etc. */
-#include <machine/locore.h> /* END_OF_VECTOR_LIST, etc. */
-#ifdef DDB
- #include <ddb/db_output.h> /* db_printf() */
-#endif /* DDB */
-
-
-#if defined(DDB) && defined(JEFF_DEBUG)
-# define DATA_DEBUG 1
-#endif
-
-
-#if DDB
-# define DEBUG_MSG db_printf
-#else
-# define DEBUG_MSG printf
-#endif /* DDB */
-
-/*
- * data access emulation for M88100 exceptions
- */
-#define DMT_BYTE 1
-#define DMT_HALF 2
-#define DMT_WORD 4
-
-static struct
-{
- unsigned char offset;
- unsigned char size;
-} dmt_en_info[16] =
-{
- {0, 0}, {3, DMT_BYTE}, {2, DMT_BYTE}, {2, DMT_HALF},
- {1, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
- {0, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
- {0, DMT_HALF}, {0, 0}, {0, 0}, {0, DMT_WORD}
-};
-
-#if DATA_DEBUG
- int data_access_emulation_debug = 0;
- static char *bytes[] =
- {
- "____", "___x", "__x_", "__xx",
- "_x__", "_x_x", "_xx_", "_xxx",
- "x___", "x__x", "x_x_", "x_xx",
- "xx__", "xx_x", "xxx_", "xxxx",
- };
- #define DAE_DEBUG(stuff) { \
- if ((data_access_emulation_debug != 0) && ( \
- data_access_emulation_debug == 0xffffffff)) { stuff ;} }
-#else
- #define DAE_DEBUG(stuff)
-#endif
-
-void data_access_emulation(unsigned *eframe)
-{
- register int x;
- register struct dmt_reg *dmtx;
- register unsigned dmax, dmdx;
- register unsigned v, reg;
-
- if (!(eframe[EF_DMT0] & DMT_VALID))
- return;
-
- for (x = 0; x < 3; x++)
- {
- dmtx = (struct dmt_reg *)&eframe[EF_DMT0+x*3];
-
- if (!dmtx->dmt_valid)
- continue;
-
- dmdx = eframe[EF_DMD0+x*3];
- dmax = eframe[EF_DMA0+x*3];
-
- DAE_DEBUG
- (
- if (dmtx->dmt_write)
- DEBUG_MSG("[DMT%d=%x: st.%c %x to %x as [%s] %s %s]\n",
- x, eframe[EF_DMT0+x*3], dmtx->dmt_das ? 's' : 'u',
- dmdx, dmax, bytes[dmtx->dmt_en],
- dmtx->dmt_doub1 ? "double": "not double",
- dmtx->dmt_lockbar ? "xmem": "not xmem");
- else
- DEBUG_MSG("[DMT%d=%x: ld.%c r%d<-%x as [%s] %s %s]\n",
- x, eframe[EF_DMT0+x*3], dmtx->dmt_das ? 's' : 'u',
- dmtx->dmt_dreg, dmax, bytes[dmtx->dmt_en],
- dmtx->dmt_doub1 ? "double": "not double",
- dmtx->dmt_lockbar ? "xmem": "not xmem");
- )
-
- dmax += dmt_en_info[dmtx->dmt_en].offset;
- reg = dmtx->dmt_dreg;
-
- if ( ! dmtx->dmt_lockbar)
- {
- /* the fault is not during an XMEM */
-
- if (x == 2 && dmtx->dmt_doub1)
- {
- /* pipeline 2 (earliest stage) for a double */
-
- if (dmtx->dmt_write)
- {
- /* STORE DOUBLE WILL BE RE-INITIATED BY rte */
- }
- else
- {
- /* EMULATE ld.d INSTRUCTION */
- v = do_load_word(dmax, dmtx->dmt_das);
- if (reg != 0)
- eframe[EF_R0 + reg] = v;
- v = do_load_word(dmax ^ 4, dmtx->dmt_das);
- if (reg != 31)
- eframe[EF_R0 + reg + 1] = v;
- }
- }
- else /* not pipeline #2 with a double */
- {
- if (dmtx->dmt_write) switch (dmt_en_info[dmtx->dmt_en].size)
- {
- case DMT_BYTE:
- DAE_DEBUG(DEBUG_MSG("[byte %x -> [%x(%c)]\n",
- dmdx & 0xff, dmax, dmtx->dmt_das ? 's' : 'u'))
- do_store_byte(dmax, dmdx, dmtx->dmt_das);
- break;
- case DMT_HALF:
- DAE_DEBUG(DEBUG_MSG("[half %x -> [%x(%c)]\n",
- dmdx & 0xffff, dmax, dmtx->dmt_das ? 's' : 'u'))
- do_store_half(dmax, dmdx, dmtx->dmt_das);
- break;
- case DMT_WORD:
- DAE_DEBUG(DEBUG_MSG("[word %x -> [%x(%c)]\n",
- dmdx, dmax, dmtx->dmt_das ? 's' : 'u'))
- do_store_word(dmax, dmdx, dmtx->dmt_das);
- break;
- }
- else /* else it's a read */
- {
- switch (dmt_en_info[dmtx->dmt_en].size)
- {
- case DMT_BYTE:
- v = do_load_byte(dmax, dmtx->dmt_das);
- if (!dmtx->dmt_signed)
- v &= 0x000000ff;
- break;
- case DMT_HALF:
- v = do_load_half(dmax, dmtx->dmt_das);
- if (!dmtx->dmt_signed)
- v &= 0x0000ffff;
- break;
- case DMT_WORD:
- default: /* 'default' just to shut up lint */
- v = do_load_word(dmax, dmtx->dmt_das);
- break;
- }
- if (reg == 0) {
- DAE_DEBUG(DEBUG_MSG("[no write to r0 done]\n"));
- }
- else
- {
- DAE_DEBUG(DEBUG_MSG("[r%d <- %x]\n",
- reg, v));
- eframe[EF_R0 + reg] = v;
- }
- }
- }
- }
- else /* if lockbar is set... it's part of an XMEM */
- {
- /*
- * According to Motorola's "General Information",
- * the dmt_doub1 bit is never set in this case, as it should be.
- * They call this "general information" - I call it a f*cking bug!
- *
- * Anyway, if lockbar is set (as it is if we're here) and if
- * the write is not set, then it's the same as if doub1
- * was set...
- */
- if ( ! dmtx->dmt_write)
- {
- if (x != 2)
- {
- /* RERUN xmem WITH DMD(x+1) */
- x++;
- dmdx = eframe[EF_DMD0 + x*3];
- }
- else
- {
- /* RERUN xmem WITH DMD2 */
- }
-
- if (dmt_en_info[dmtx->dmt_en].size == DMT_WORD)
- v = do_xmem_word(dmax, dmdx, dmtx->dmt_das);
- else
- v = do_xmem_byte(dmax, dmdx, dmtx->dmt_das);
- eframe[EF_R0 + reg] = v;
- }
- else
- {
- if (x == 0)
- {
- eframe[EF_R0 + reg] = dmdx;
- eframe[EF_SFIP] = eframe[EF_SNIP];
- eframe[EF_SNIP] = eframe[EF_SXIP];
- eframe[EF_SXIP] = 0;
- /* xmem RERUN ON rte */
- eframe[EF_DMT0] = 0;
- return;
- }
- }
- }
- }
- eframe[EF_DMT0] = 0;
-}
-
-/*
- ***********************************************************************
- ***********************************************************************
- */
-#define SIGSYS_MAX 501
-#define SIGTRAP_MAX 511
-
-#define EMPTY_BR 0xC0000000U /* empty "br" instruction */
-#define NO_OP 0xf4005800U /* "or r0, r0, r0" */
-
-typedef struct
-{
- unsigned word_one,
- word_two;
-} m88k_exception_vector_area;
-
-#define BRANCH(FROM, TO) (EMPTY_BR | ((unsigned)(TO) - (unsigned)(FROM)) >> 2)
-
-#define SET_VECTOR(NUM, to, VALUE) { \
- unsigned _NUM = (unsigned)(NUM); \
- unsigned _VALUE = (unsigned)(VALUE); \
- vector[_NUM].word_one = NO_OP; \
- vector[_NUM].word_two = BRANCH(&vector[_NUM].word_two, _VALUE); \
-}
-
-
-/*
- * vector_init(vector, vector_init_list)
- *
- * This routine sets up the m88k vector table for the running processor.
- * It is called with a very little stack, and interrupts disabled,
- * so don't call any other functions!
- */
-void vector_init(
- m88k_exception_vector_area *vector,
- unsigned *vector_init_list)
-{
- register unsigned num;
- register unsigned vec;
- extern void sigsys(), sigtrap(), stepbpt(), userbpt();
-
- for (num = 0; (vec = vector_init_list[num]) != END_OF_VECTOR_LIST; num++)
- {
- if (vec != PREDEFINED_BY_ROM)
- SET_VECTOR(num, to, vec);
- }
-
- while (num < 496)
- SET_VECTOR(num++, to, sigsys);
- num++; /* skip 496, BUG ROM vector */
-#if 0
- while (num <= SIGSYS_MAX)
- SET_VECTOR(num++, to, sigsys);
-
- while (num <= SIGTRAP_MAX)
- SET_VECTOR(num++, to, sigtrap);
-
- SET_VECTOR(504, to, stepbpt);
- SET_VECTOR(511, to, userbpt);
- vector[496].word_one = 496 * 4;
- vector[497].word_two = 497 * 4;
-#endif
-}
-
-/* JEFF_DEBUG stuff */
-#include <machine/asm_macro.h>
-
-#ifdef JUNK
-#define MAX_XPR_COUNT 1000
-struct {
- task_t task;
- char *fmt;
- unsigned arg1;
- unsigned arg2;
-} raw_xpr_data[MAX_XPR_COUNT];
-unsigned volatile raw_xpr_lock = 0;
-unsigned raw_xpr_index = 0;
-
-void _raw_xpr(char *fmt, unsigned b, unsigned c, task_t t)
-{
- unsigned myindex;
- m88k_psr_type psr = disable_interrupts_return_psr();
- simple_lock(&raw_xpr_lock);
- if (raw_xpr_index < (MAX_XPR_COUNT - 1)) {
- myindex = raw_xpr_index++;
- } else {
- myindex = 0;
- raw_xpr_index = 1;
- }
- simple_unlock(&raw_xpr_lock);
- set_psr(psr);
-
- raw_xpr_data[myindex].task = t;
- raw_xpr_data[myindex].fmt = fmt;
- raw_xpr_data[myindex].arg1 = b;
- raw_xpr_data[myindex].arg2 = c;
-}
-
-void raw_xpr_dump(int skipcount)
-{
- int i, index = raw_xpr_index + 1;
-
- raw_xpr_lock = 1; /* forcefully grab the lock */
-
- if (index >= MAX_XPR_COUNT)
- index = 0;
- else if (raw_xpr_data[index].task == 0)
- index = 0; /* hasn't wrapped yet, so start at the beginning */
-
- for (i = 1; i < MAX_XPR_COUNT; i++) {
- if (raw_xpr_data[index].task == 0 || raw_xpr_data[index].fmt == 0)
- break; /* all done */
- if (skipcount-- <= 0)
- {
- db_printf("%04d: ", i);
- if (db_lookup_task(raw_xpr_data[index].task) < 0)
- {
- /* task no longer valid */
- db_printf("<task %x, fmt %x, arg %x, arg %x>\n",
- raw_xpr_data[index].task,
- raw_xpr_data[index].fmt,
- raw_xpr_data[index].arg1,
- raw_xpr_data[index].arg2);
- } else {
- char buffer[120];
- buffer[0] = '\0';
- db_read_bytes(raw_xpr_data[index].fmt,
- sizeof(buffer),
- buffer,
- raw_xpr_data[index].task);
- buffer[sizeof(buffer)-2] = '\n';
- buffer[sizeof(buffer)-1] = '\0';
-
- db_printf(buffer,
- raw_xpr_data[index].arg1,
- raw_xpr_data[index].arg2);
- }
- }
- if (++index >= MAX_XPR_COUNT)
- index = 0;
- }
-
- raw_xpr_lock = 0;
-}
-#endif /* JUNK */
diff --git a/sys/arch/mvme88k/m88k/m1x7_init.c b/sys/arch/mvme88k/m88k/m1x7_init.c
deleted file mode 100644
index 705221fc098..00000000000
--- a/sys/arch/mvme88k/m88k/m1x7_init.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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/m88k/m88100_fp.S b/sys/arch/mvme88k/m88k/m88100_fp.S
deleted file mode 100644
index c51a862ace8..00000000000
--- a/sys/arch/mvme88k/m88k/m88100_fp.S
+++ /dev/null
@@ -1,2463 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 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
- */
-
-/* Floating point trouble routines */
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#define __LUNA_SUB_H__
-
-#ifndef NDEBUG /* no debugging */
-#define NDEBUG
-#endif
-
-#ifdef NDEBUG
-# define _LABEL(NAME) NAME:
-#else
-# define _LABEL(NAME) NAME: global NAME
-#endif
-# define LABEL(NAME) NAME: global NAME
-
-#define psr cr1
-#define spsr cr2
-#define ssb cr3
-#define scip cr4
-#define snip cr5
-#define sfip cr6
-#define vbr cr7
-#define dmt0 cr8
-#define scratch1 cr18
-#define scratch2 cr20
-#define fpecr fcr0
-#define s1hi fcr1
-#define s1lo fcr2
-#define s2hi fcr3
-#define s2lo fcr4
-#define pcr fcr5
-#define manthi fcr6
-#define mantlo fcr7
-#define impcr fcr8
-#define fpsr fcr62
-#define fpcr fcr63
-#define valid 1
-#define exception 0
-#define exc_disable 0
-#define FP_disable 3
-#define dexc 27
-#define serial 29
-#define destsize 10
-#define inexact 0
-#define overflow 1
-#define underflow 2
-#define divzero 3
-#define oper 4
-#define sign 31
-#define s1size 9
-#define s2size 7
-#define dsize 5
-#define full 1
-#define fault 0
-#define FADDop 0x05
-#define FSUBop 0x06
-#define FCMPop 0x07
-#define FMULop 0x00
-#define FDIVop 0x0e
-#define FSQRTop 0x0f
-#define FLTop 0x04
-#define INTop 0x09
-#define NINTop 0x0a
-#define TRNCop 0x0b
-#define mode 31
-#define s1sign 9
-#define s2sign 8
-#define s1nan 7
-#define s2nan 6
-#define s1inf 5
-#define s2inf 4
-#define s1zero 3
-#define s2zero 2
-#define s1denorm 1
-#define s2denorm 0
-#define sigbit 19
-#define sigbits 22
-#define sigbitd 19
-#define nc 0
-#define cp 1
-#define eq 2
-#define ne 3
-#define gt 4
-#define le 5
-#define lt 6
-#define ge 7
-#define ou 8
-#define ib 9
-#define in 10
-#define ob 11
-#define FRAMESIZE 200
-#define SWITCHUSER 128
-#if 0
-#define XR1 4
-#define XR2 8
-#define XR3 12
-#define XR4 16
-#define XR5 20
-#define XR6 24
-#define XR7 28
-#define XR8 32
-#define XR9 36
-#define XR10 40
-#define XR11 44
-#define XR12 48
-#define XR13 52
-#define XR14 56
-#define XR15 60
-#define XR16 64
-#define XR17 68
-#define XR18 72
-#define XR19 76
-#define XR20 80
-#define XR21 84
-#define XR22 88
-#define XR23 92
-#define XR24 96
-#define XR25 100
-#define XR26 104
-#define XR27 108
-#define XR28 112
-#define XR29 116
-#define XR30 120
-#define XR31 124
-#define XFPSR 128
-#define XFPCR 132
-#define XFPECR 136
-#define XS1HI 140
-#define XS1LO 144
-#define XS2HI 148
-#define XS2LO 152
-#define XPCR 156
-#define XMANTHI 140
-#define XMANTLO 144
-#define XIMPCR 148
-#define XSPSR 160
-#define XSSB 164
-#define XSNIP 168
-#define XSFIP 172
-#define XRETADDR 176
-#define XHANDRETADDR 180
-#define XHANDFPECR 184
-#define XHANDPR 188
-#define XHANDIMP 192
-#endif
-#define STKSTATE 196
-#define handtrap 134
-#define modehi 30
-#define modelo 29
-#define rndhi 15
-#define rndlo 14
-#define efunf 7
-#define efovf 6
-#define efinx 5
-#define hiddens 23
-#define hiddend 20
-#define NUMFRAME 10
-#define SIGILL 4
-#define SIGFPEPR 8
-#define u_sfu1full 0x4
-#define u_xcpt 0x8
-#define USIZE 0x0ff0
-#endif
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef LOCORE
-#define LOCORE
-
-#ifndef ASSEMBLER /* predefined by ascpp, at least */
-#define ASSEMBLER
-#endif
-
-#include <machine/trap.h>
-#include "assym.s"
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
-#endif
-#define MARK or r21, r0, __LINE__
-
- text
- align 4
- global _Xfp_precise
-_Xfp_precise:
- or r29, r3, r0 ; r29 is now the E.F.
- subu r31, r31, 40
- st r1, r31, 32
- st r29, r31, 36
-
- ld r2, r29, EF_FPSR * 4
- ld r3, r29, EF_FPCR * 4
- ld r4, r29, EF_FPECR * 4
- ld r5, r29, EF_FPHS1 * 4
- ld r6, r29, EF_FPLS1 * 4
- ld r7, r29, EF_FPHS2 * 4
- ld r8, r29, EF_FPLS2 * 4
- ld r9, r29, EF_FPPT * 4
-
-
- ;Load into r1 the return address for the 0 handlers. Looking
- ;at FPECR, branch to the appropriate 0 handler. However,
- ;if none of the 0 bits are enabled, then a floating point
- ;instruction was issued with the floating point unit disabled. This
- ;will cause an unimplemented opcode 0.
-
- or.u r1,r0,hi16(wrapup) ;load return address of function
- or r1,r1,lo16(wrapup)
-2: bb0 6,r4, 3f ;branch to FPunimp if bit set
- br FPuimp
-3: bb0 7,r4, 4f ;branch to FPintover if bit set
- br _FPintover
-4: ; bb0 5,r4, 5f ;branch to FPpriviol if bit set
- ; br _FPpriviol
-5: bb0 4,r4, 6f ;branch to FPresoper if bit set
- br _FPresoper
-6: bb0 3,r4, 7f ;branch to FPdivzero if bit set
- br _FPdivzero
-7:
- or.u r4, r4, 0xffff
-
-FPuimp: global FPuimp
-fp_p_trap:
- subu r31,r31,40 /* allocate stack */
- st r1,r31,36 /* save return address */
- st r3,r31,32 /* save exception frame */
- or r2,r0,T_FPEPFLT /* load trap type */
- or r3, r29, r0
- bsr _trap /* trap */
- ld r1,r31,36 /* recover return address */
- addu r31,r31,40 /* deallocate stack */
- br fp_p_return
-
- ;To write back the results to the user registers, disable exceptions
- ;and the floating point unit. Write FPSR and FPCR and load the SNIP
- ;and SFIP.
- ;r5 will contain the upper word of the result
- ;r6 will contain the lower word of the result
-
-wrapup: global wrapup
- tb1 0,r0,0 ;make sure all floating point operations
- ;have finished
- ldcr r10, cr1 ;load the PSR
- or r10, r10, 0x2 ;disable interrupts
- stcr r10, cr1
-#if 0
-Why is this done? -jfriedl
- or r10, r10, 0x8 ;set SFU 1 disable bit, disable SFU 1
- stcr r10, cr1
-#endif
- ld r1, r31, 32
- ld r29, r31, 36
- addu r31, r31, 40
-
- fstcr r2, fpsr ;write revised value of FPSR
- fstcr r3, fpcr ;write revised value of FPCR
-
- ;result writeback routine
- addu r3, r29, EF_R0 * 4
- extu r2, r9, 5<0> ;get 5 bits of destination register
- bb0 5, r9, writesingle ;branch if destination is single
-
-;writedouble here
- st r5, r3 [r2] ;write high word
- add r2, r2, 1 ;for double, the low word is the
- ;unspecified register
- clr r2, r2, 27<5> ;perform equivalent of mod 32
-writesingle:
- st r6, r3 [r2] ;write low word into memory
-
-fp_p_return:
- jmp r1
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- text
- global _FPdivzero
-
-
-;Check if the numerator is zero. If the numerator is zero, then handle
-;this instruction as you would a 0/0 invalid operation.
-
-_FPdivzero:
- st r1,r31,0 ;save return address
- bb1 s1size,r9,1f ;branch if numerator double
-/* single number */
- clr r10,r5,1<sign> ;clear sign bit
- extu r11,r6,3<29> ;grab upper bits of lower word
- or r10,r10,r11 ;combine ones of mantissa
- bcnd eq0,r10,resoper ;numerator is zero, handle reserved
- ;operand
- br setbit ;set divzero bit
-1:
-/* double number */
- clr r10,r5,1<sign> ;clear sign bit
- or r10,r10,r6 ;or high and low words
- bcnd ne0,r10,setbit ;set divzero bit
-
-;The numerator is zero, so handle the invalid operation by setting the
-;invalid operation bit and branching to the user handler if there is one
-;or writing a quiet NaN to the destination.
-
-resoper:
- set r2,r2,1<oper> ;set bit in FPSR
-#ifdef HANDLER
- bb0 oper,r3,noreshand ;branch to execute default handling for
- ;reserved operands
- bsr _handler ;branch to user handler
- br FP_div_return ;return from function
-#endif
-
-noreshand:
- set r5,r0,0<0> ;put a NaN in high word
- set r6,r0,0<0> ;put a NaN in low word
- br FP_div_return ;return from subroutine
- ;writing to a word which may be ignored
- ;is just as quick as checking the precision
- ;of the destination
-
-;The operation is divide by zero, so set the divide by zero bit in the
-;FPSR. If the user handler is set, then go to the user handler, else
-;go to the default mode.
-
-setbit:
-#ifdef HANDLER
- set r2,r2,1<divzero> ;set bit in FPSR
- bb0 divzero,r3,default ;go to default routine if no handler
- bsr _handler ;execute handler routine
- br FP_div_return ;return from subroutine
-#endif
-
-
-;Considering the sign of the numerator and zero, write a correctly
-;signed infinity of the proper precision into the destination.
-
-default:
- bb1 dsize,r9,FPzero_double ;branch to handle double result
-FPzero_single:
- clr r10,r5,31<0> ;clear all of S1HI except sign bit
- xor r10,r7,r10 ;xor the sign bits of the operands
- or.u r6,r0,0x7f80 ;load single precision infinity
- br.n FP_div_return ;return from subroutine
- or r6,r6,r10 ;load correctly signed infinity
-
-FPzero_double:
- clr r10,r5,31<0> ;clear all of S1HI except sign bit
- xor r10,r7,r10 ;xor the sign bits of the operands
- or.u r5,r0,0x7ff0 ;load double precision infinity
- or r5,r5,r10 ;load correctly signed infinity
- or r6,r0,r0 ;clear lower word of double
-
-FP_div_return:
- ld r1,r31,0 ;load return address
- jmp r1 ;return from subroutine
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- text
-
-
-;Both NINT and TRNC require a certain rounding mode, so check which
-;instruction caused the integer conversion overflow. Use a substitute
-;FPCR in r1, and modify the rounding mode if the instruction is NINT or TRNC.
-
-_FPintover: global _FPintover
- extu r10,r9,5<11> ;extract opcode
- cmp r11,r10,INTop ;see if instruction is INT
- st r1,r31,0 ;save return address
- bb1.n eq,r11,checksize ;instruction is INT, do not modify
- ;rounding mode
- or r1,r0,r3 ;load FPCR into r1
- cmp r11,r10,NINTop ;see if instruction is NINT
- bb1 eq,r11,NINT ;instruction is NINT
-
-TRNC: clr r1,r1,2<rndlo> ;clear rounding mode bits,
- ;instruction is TRNC
- br.n checksize ;branch to check size
- set r1,r1,1<rndlo> ;make rounding mode round towards zero
-
-NINT: clr r1,r1,2<rndlo> ;make rounding mode round to nearest
-
-
-;See whether the source is single or double precision.
-
-checksize: bb1 s2size,r9,checkdoub ;S2 is double, branch to see if there
-;is a false alarm
-
-
-;An integer has more bits than the mantissa of a single precision floating
-;point number, so to check for false alarms (i.e. valid conversion), simply
-;check the exponents. False alarms are detected for 2**30 to (2**30) - 1 and
-;-2**30 to -2**31. Only seven bits need to be looked at since an exception
-;will not occur for the other half of the numbering system.
-;To speed up the processing, first check to see if the exponent is 32 or
-;greater.
-
-;This code was originally written for the exponent in the control
-;register to have the most significant bit (8 - single, 11 - double)
-;flipped and sign extended. For precise exceptions, however, the most
-;significant bit is only sign extended. Therefore, the code was chopped
-;up so that it would work for positive values of real exponent which were
-;only sign extended.
-
-checksing: extu r10,r7,7<20> ;internal representation for single
-;precision is IEEE 8 bits sign extended
-;to 11 bits; for real exp. = 30, the
-;above instruction gives a result exp.
-;that has the MSB flipped and sign
-;extended like in the IMPCR
- cmp r11,r10,31 ;compare to 32,but exp. off by 1
-;these 2 instructions to speed up valid
-;execution of valid cases
- bb1 ge,r11,overflw ;valid case, perform overflow routine
- bb1 sign,r7,checksingn ;source operand is negative
-
-;If the number is positve and the exponent is greater than 30, than it is
- ;overflow.
-
-checksingp: cmp r10,r10,29 ;compare to 30, but exp. off by 1
- bb1 gt,r10,overflw ;no false alarm, its overflow
- br conversionsp ;finish single precision conversion
-
-;If the number is negative, and the exponent is 30, or 31 with a mantissa
-;of 0, then it is a false alarm.
-
-checksingn: cmp r11,r10,30 ;compare to 31,but exp. off by 1
- bb1 lt,r11,conversionsn ;exp. less than 31, so convert
- extu r10,r8,3<29> ;get upper three bits of lower mantissa
- mak r12,r7,20<3> ;get upper 20 bits of mantissa
- or r10,r10,r12 ;form complete mantissa
- bcnd eq0,r10,conversionsn ;complete conversion if mantissa is 0
- br overflw ;no false alarm, its overflow
-
-
-;False alarms are detected for 2**30 to (2**30) - 1 and
-;-2**30 to -2**31. Only seven bits need to be looked at since an exception
-;will not occur for the other half of the numbering system.
-;To speed up the processing, first check to see if the exponent is 32 or
-;greater. Since there are more mantissa bits than integer bits, rounding
-;could cause overflow. (2**31) - 1 needs to be checked so that it does
-;not round to 2**31, and -2**31 needs to be checked in case it rounds to
-;-((2**31) + 1).
-
-checkdoub: extu r10,r7,10<20> ;internal representation for double
-;precision is the same IEEE 11 bits
-;for real exp. = 30, the
-;above instruction gives a result exp.
-;that has the MSB flipped and sign
-;extended like in the IMPCR
- cmp r11,r10,31 ;compare to 32,but exp. off by 1
-;these 2 instructions to speed up valid
-;execution of valid cases
- bb1 ge,r11,overflw ;valid case, perform overflow routine
- bb1 sign,r7,checkdoubn ;source operand is negative
-
-;If the exponent is not 31, then the floating point number will be rounded
-;before the conversion is done. A branch table is set up with bits 4 and 3
-;being the rounding mode, and bits 2, 1, and 0 are the guard, round, and
-;sticky bits.
-
-checkdoubp: cmp r11,r10,30 ;compare to 31, but exponent off by 1
- bb1 eq,r11,overflw ;no false alarm, its overflow
- extu r12,r8,1<22> ;get LSB for integer with exp. = 30
- mak r12,r12,1<2> ;start to set up field for branch table
- extu r11,r8,1<21> ;get guard bit
- mak r11,r11,1<1> ;set up field for branch table
- or r12,r11,r12 ;set up field for branch table
- extu r11,r8,21<0> ;get bits for sticky bit
- bcnd eq0,r11,nostickyp ;do not set sticky
- set r12,r12,1<0> ;set sticky bit
-nostickyp: rot r11,r1,0<rndlo> ;shift rounding mode to 2 LSB''s
- mak r11,r11,2<3> ;set up field, clear other bits
- or r12,r11,r12 ;set up field for branch table
- lda r12,r0[r12] ;scale r12
- or.u r12,r12,hi16(ptable) ;load pointer into table
- addu r12,r12,lo16(ptable)
- jmp r12 ;jump into branch table
-
-ptable: br conversiondp
-p00001: br conversiondp
-p00010: br conversiondp
-p00011: br paddone
-p00100: br conversiondp
-p00101: br conversiondp
-p00110: br paddone
-p00111: br paddone
-p01000: br conversiondp
-p01001: br conversiondp
-p01010: br conversiondp
-p01011: br conversiondp
-p01100: br conversiondp
-p01101: br conversiondp
-p01110: br conversiondp
-p01111: br conversiondp
-p10000: br conversiondp
-p10001: br conversiondp
-p10010: br conversiondp
-p10011: br conversiondp
-p10100: br conversiondp
-p10101: br conversiondp
-p10110: br conversiondp
-p10111: br conversiondp
-p11000: br conversiondp
-p11001: br paddone
-p11010: br paddone
-p11011: br paddone
-p11100: br conversiondp
-p11101: br paddone
-p11110: br paddone
-p11111: br paddone
-
-;Add one to the bit of the mantissa which corresponds to the LSB of an
-;integer. If the mantissa overflows, then there is a valid integer
-;overflow conversion; otherwise, the mantissa can be converted to the integer.
-
-paddone: or r10,r0,r0 ;clear r10
- set r10,r10,1<22> ;set LSB bit to 1 for adding
- addu.co r8,r8,r10 ;add the 1 obtained from rounding
- clr r11,r7,12<20> ;clear exponent and sign
- addu.ci r11,r0,r11 ;add carry
- bb1 20,r11,overflw ;overflow to 2**31, abort the rest
- br.n conversiondp ;since the exp. was 30, and the exp.
- ;did not round up to 31, the largest
- ;number that S2 could become is 2**31-1
- or r7,r0,r11 ;store r11 into r7 for conversion
-
-;Now check for negative double precision sources. If the exponent is 30,
-;then convert the false alarm. If the exponent is 31, then check the mantissa
-;bits which correspond to integer bits. If any of them are a one, then there
-;is overflow. If they are zero, then check the guard, round, and sticky bits.
-;Round toward zero and positive will not cause a roundup, but round toward
-;nearest and negative may, so perform those roundings. If there is no overflow,
- ;then convert and return from subroutine.
-
-checkdoubn: cmp r11,r10,29 ;compare to 30, but exp. off by 1
- bb1 eq,r11,conversiondn ;false alarm if exp. = 30
- extu r10,r8,11<21> ;check upper bits of lower mantissa
- bcnd ne0,r10,overflw ;one of the bits is a 1, so overflow
- extu r10,r7,20<0> ;check upper bits of upper mantissa
- bcnd ne0,r10,overflw ;one of the bits is a 1, so overflow
- bb0 rndlo,r1,possround ;rounding mode is either round near or
- ;round negative, which may cause a
- ;round
- br.n FPintov_return ;round positive, which will not cause a
- ;round
- set r6,r0,1<sign> ;rounding mode is either round zero or
-possround: extu r12,r8,1<20> ;get guard bit
- extu r11,r8,20<0> ;get bits for sticky bit
- bcnd.n eq0,r11,nostickyn ;do not set sticky
- mak r12,r12,1<1> ;set up field for branch table
- set r12,r12,1<0> ;set sticky bit
-nostickyn: bb1 rndhi,r1,negative ;rounding mode is negative
-nearest: cmp r12,r12,3 ;are both guard and sticky set
- bb1 eq,r12,overflw ;both guard and sticky are set,
- ;so signal overflow
- or r6,r0,r0 ;clear destination register r6
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<sign> ;set the sign bit and take care of
- ;this special case
-negative: bcnd ne0,r12,overflw ;-2**31 will be rounded to -(2**31+1),
- ;so signal overflow
- or r6,r0,r0 ;clear destination register r6
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<sign> ;set the sign bit and take care of
- ;this special case
-
- ;since the exp. was 30, and there was
- ;no round-up, the largest number that
- ;S2 could have been was 2**31 - 1
-
-
- ;Convert the single precision positive floating point number.
-
-conversionsp: extu r6,r8,3<29> ;extract lower bits of integer
- mak r6,r6,3<7> ;shift left to correct place in integer
- mak r10,r7,20<10> ;shift left upper bits of integer
- or r6,r6,r10 ;form most of integer
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<30> ;set hidden one
-
-
- ;Convert the single precision negative floating point number.
-
-conversionsn: bb1 eq,r11,exp31s ;use old r11 to see if exp. is 31
- extu r6,r8,3<29> ;extract lower bits of mantissa
- mak r6,r6,3<7> ;shift left to correct place in integer
- mak r10,r7,20<10> ;shift left upper bits of integer
- or r6,r6,r10 ;form most of integer
- set r6,r6,1<30> ;set hidden one
- or.c r6,r0,r6 ;negate result
- br.n FPintov_return ;return from subroutine
- addu r6,r6,1 ;add 1 to get 2''s complement
-exp31s: or r6,r0,r0 ;clear r6
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<sign> ;set sign bit
-
-
- ;Convert the double precision positive floating point number.
-
-conversiondp: extu r6,r8,10<22> ;extract lower bits of integer
- mak r10,r7,20<10> ;shift left upper bits of integer
- or r6,r6,r10 ;form most of integer
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<30> ;set hidden one
-
-
- ;Convert the double precision negative floating point number. The number,
- ;whose exponent is 30, must be rounded before converting. Bits 4 and 3 are
- ;the rounding mode, and bits 2, 1, and 0 are the guard, round, and sticky
- ;bits for the branch table.
-
-conversiondn: extu r12,r8,1<22> ;get LSB for integer with exp. = 30
- mak r12,r12,1<2> ;start to set up field for branch table
- extu r11,r8,1<21> ;get guard bit
- mak r11,r11,1<1> ;set up field for branch table
- or r12,r11,r12 ;set up field for branch table
- extu r11,r8,21<0> ;get bits for sticky bit
- bcnd eq0,r11,nostkyn ;do not set sticky
- set r12,r12,1<0> ;set sticky bit
-nostkyn: rot r11,r1,0<rndlo> ;shift rounding mode to 2 LSB''s
- mak r11,r11,2<3> ;set up field, clear other bits
- or r12,r11,r12 ;set up field for branch table
- lda r12,r0[r12] ;scale r12
- or.u r12,r12,hi16(ntable);load pointer into table
- addu r12,r12,lo16(ntable)
- jmp r12 ;jump into branch table
-
-ntable: br nnoaddone
-n00001: br nnoaddone
-n00010: br nnoaddone
-n00011: br naddone
-n00100: br nnoaddone
-n00101: br nnoaddone
-n00110: br naddone
-n00111: br naddone
-n01000: br nnoaddone
-n01001: br nnoaddone
-n01010: br nnoaddone
-n01011: br nnoaddone
-n01100: br nnoaddone
-n01101: br nnoaddone
-n01110: br nnoaddone
-n01111: br nnoaddone
-n10000: br nnoaddone
-n10001: br naddone
-n10010: br naddone
-n10011: br naddone
-n10100: br nnoaddone
-n10101: br naddone
-n10110: br naddone
-n10111: br naddone
-n11000: br nnoaddone
-n11001: br nnoaddone
-n11010: br nnoaddone
-n11011: br nnoaddone
-n11100: br nnoaddone
-n11101: br nnoaddone
-n11110: br nnoaddone
-n11111: br nnoaddone
-
-
- ;Add one to the mantissa, and check to see if it overflows to -2**31.
-;The conversion is done in nnoaddone:.
-
-naddone: or r10,r0,r0 ;clear r10
- set r10,r10,1<22> ;set LSB bit to 1 for adding
- add.co r8,r8,r10 ;add the 1 obtained from rounding
- clr r7,r7,12<20> ;clear exponent and sign
- add.ci r7,r0,r7 ;add carry
- bb1 20,r7,maxneg ;rounded to -2**31,handle separately
- ;the exponent was originally 30
-nnoaddone: extu r6,r8,11<22> ;extract lower bits of integer
- mak r10,r7,20<10> ;shift left upper bits of integer
- or r6,r6,r10 ;form most of integer
- set r6,r6,1<30> ;set hidden one
- or.c r6,r0,r6 ;negate integer
- br.n FPintov_return ;return from subroutine
- addu r6,r6,1 ;add 1 to get 2''s complement
-
-maxneg: or r6,r0,r0 ;clear integer
- br.n FPintov_return ;return from subroutine
- set r6,r6,1<sign> ;set sign bit
-
-
- ;For valid overflows, check to see if the integer overflow user handler is
- ;set. If it is set, then go to user handler, else write the correctly
- ;signed largest integer.
-
-overflw:
-#ifdef HANDLER
- bb0.n oper,r3,nohandler ;do not go to user handler routine
- set r2,r2,1<oper> ;set invalid operand bit
- bsr _handler ;go to user handler routine
- br FPintov_return ;return from subroutine
-nohandler:
-#endif
- bb0.n sign,r7,FPintov_return ;if positive then return from subroutine
- set r6,r6,31<0> ;set result to largest positive integer
- or.c r6,r0,r6 ;negate r6,giving largest negative int.
-
-FPintov_return: ld r1,r31,0 ;load return address from memory
- jmp r1 ;return from subroutine
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- text
-
-
-;Some instructions only have the S2 operations, so clear S1HI and S1LO
-;for those instructions so that the previous contents of S1HI and S1LO
-;do not influence this instruction.
-
-LABEL(_FPresoper)
- st r1, r31, 0
- extu r10,r9,5<11> ;extract opcode
-; cmp r11,r10,FSQRTop ;compare to FSQRT
-; bb1 eq,r11,S1clear ;clear S1 if instruction only had S2 operand
- cmp r11,r10,INTop ;compare to INT
- bb1 eq,r11,S1clear ;clear S1 if instruction only had S2 operand
- cmp r11,r10,NINTop ;compare to NINT
- bb1 eq,r11,S1clear ;clear S1 if instruction only had S2 operand
- cmp r11,r10,TRNCop ;compare to TRNC
- bb0 eq,r11,opercheck ;check for reserved operands
-
-_LABEL(S1clear)
- or r5,r0,r0 ;clear any NaN''s, denorms, or infinities
- or r6,r0,r0 ;that may be left in S1HI,S1LO from a
- ;previous instruction
-
-;r12 contains the following flags:
-; bit 9 -- s1sign
-; bit 8 -- s2sign
-; bit 7 -- s1nan
-; bit 6 -- s2nan
-; bit 5 -- s1inf
-; bit 4 -- s2inf
-; bit 3 -- s1zero
-; bit 2 -- s2zero
-; bit 1 -- s1denorm
-; bit 0 -- s2denorm
-
-;Using code for both single and double precision, check if S1 is either
-;a NaN or infinity and set the appropriate flags in r12. Then check if
-;S2 is a NaN or infinity. If it is a NaN, then branch to the NaN routine.
-
-
-_LABEL(opercheck)
- extu r10,r5,11<20> ;internal representation for double
- bb1.n s1size,r9,S1NaNdoub ;S1 is double precision
- or r12,r0,r0 ;clear operand flag register
-_LABEL(S1NaNsing)
- xor r10,r10,0x0080 ;internal representation for single
- ext r10,r10,8<0> ;precision is IEEE 8 bits sign extended
- ;to 11 bits; for real exp. > 0, the
- ;above instructions gives a result exp.
- ;that has the MSB flipped and sign
- ;extended like in the IMPCR
- cmp r11,r10,127 ;Is exponent equal to IEEE 255 (internal 127)
- bb1 ne,r11,S2NaN ;source 1 is not a NaN or infinity
- mak r10,r5,20<0> ;load r10 with upper bits of S1 mantissa
- extu r11,r6,3<29> ;get 3 upper bits of lower word
- or r11,r10,r11 ;combine any existing 1''s
- bcnd eq0,r11,noS1NaNs ;since r11 can only hold 0 or a positive
- ;number, branch to noS1NaN when eq0
- br.n S2NaN ;see if S2 has a NaN
- set r12,r12,1<s1nan> ;indicate that S1 has a NaN
-_LABEL(noS1NaNs)
- br.n S2NaN ;check contents of S2
- set r12,r0,1<s1inf> ;indicate that S1 has an infinity
-
-_LABEL(S1NaNdoub)
- xor r10,r10,0x0400 ;precision is the same IEEE 11 bits
- ;The
- ;above instructions gives a result exp.
- ;that has the MSB flipped and sign
- ;extended like in the IMPCR
- cmp r11,r10,1023 ;Is exp. equal to IEEE 2047 (internal 1023)
- bb1 ne,r11,S2NaN ;source 1 is not a NaN or infinity
- mak r10,r5,20<0> ;load r10 with upper bits of S1 mantissa
- or r11,r6,r10 ;combine existing 1''s of mantissa
- bcnd eq0,r11,noS1NaNd ;since r11 can only hold 0 or a positive
- ;number, branch to noS1NaN when eq0
- br.n S2NaN ;see if S2 has a NaN
- set r12,r12,1<s1nan> ;indicate that S1 has a NaN
-_LABEL(noS1NaNd)
- set r12,r0,1<s1inf> ;indicate that S1 has an infinity
-
-_LABEL(S2NaN)
- bb1.n s2size,r9,S2NaNdoub ;S1 is double precision
- extu r10,r7,11<20> ;internal representation for double
-_LABEL(S2NaNsing)
- xor r10,r10,0x0080 ;internal representation for single
- ext r10,r10,8<0> ;precision is IEEE 8 bits sign extended
- ;to 11 bits; for real exp. > 0, the
- ;above instruction gives a result exp.
- ;that has the MSB flipped and sign
- ;extended like in the IMPCR
- cmp r11,r10,127 ;Is exponent equal to IEEE 255 (internal 127)
- bb1 ne,r11,inf ;source 2 is not a NaN or infinity
- mak r10,r7,20<0> ;load r10 with upper bits of S1 mantissa
- extu r11,r8,3<29> ;get 3 upper bits of lower word
- or r11,r10,r11 ;combine any existing 1''s
- bcnd eq0,r11,noS2NaNs ;since r11 can only hold 0 or a positive
- ;number, branch to noS2NaNs when eq0
- br.n _NaN ;branch to NaN routine
- set r12,r12,1<s2nan> ;indicate that s2 has a NaN
-_LABEL(noS2NaNs)
- bb0 s1nan,r12, 1f ;branch to NaN if S1 is a NaN
- br _NaN
-1: br.n _infinity ;If S1 had a NaN we would have already
- ;branched, and S2 does not have a NaN, but
- ;it does have an infinity, so branch to
- ;handle the finity
- set r12,r12,1<s2inf> ;indicate that S2 has an infinity
-
-_LABEL(S2NaNdoub)
- xor r10,r10,0x0400 ;precision is the same IEEE 11 bits
- ;The
- ;above instruction gives a result exp.
- ;that has the MSB flipped and sign
- ;extended like in the IMPCR
- cmp r11,r10,1023 ;Is exp. equal to IEEE 2047 (internal 1023)
- bb1 ne,r11,inf ;source 2 is not a NaN or infinity
- mak r10,r7,20<0> ;load r10 with upper bits of S2 mantissa
- or r11,r8,r10 ;combine existing 1''s of mantissa
- bcnd eq0,r11,noS2NaNd ;since r11 can only hold 0 or a positive
- ;number, branch to noS2NaNd when eq0
- br.n _NaN ;branch to NaN routine
- set r12,r12,1<s2nan> ;indicate that s2 has a NaN
-_LABEL(noS2NaNd)
- bb0 s1nan,r12,1f ;branch to NaN if S1 is a NaN
- br _NaN
-1: br.n _infinity ;If S1 had a NaN we would have already
- ;branched, and S2 does not have a NaN, but
- ;it does have an infinity, so branch to
- ;handle the finity
- set r12,r12,1<s2inf> ;indicate that S2 has an infinity
-
-
-;If S2 was a NaN, the routine would have already branched to NaN. If S1
-;is a NaN, then branch to NaN. If S1 is not a NaN and S2 is infinity, then
-;we would have already branched to infinity. If S1 is infinity, then branch.
-;If the routine still has not branched, then branch to denorm, the only
-;reserved operand left.
-
-_LABEL(inf)
- bb0 s1nan,r12,1f ;branch if S1 has a NaN and S2 does not
- br _NaN
-1: bb0 s1inf,r12,2f ;Neither S1 or S2 has a NaN, and we would
- ;have branched already if S2 had an
- ;infinity, so branch if S1 is infinity
-/*
- * The above "bb0 s1inf, r12,2f" had been a "bb1", but it just didn't make
- * sense (and didn't work, either), so I changed it.
- * jfriedl Dec 1, 1989.
- */
- br _infinity
-2:
-
- br _denorm ;branch to denorm, the only remaining
- ;alternative
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-;function _FPunderflow --
-;The documentation for this release give an overall description of this code.
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- global _FPunderflow
- text
-
-;First check for an underflow user handler. If there is not one, then
-;branch to the routine to make a denormalized number. Before branching
-;to the underflow user handler, add 192 to a single precision exponent
-;and 1536 to a double precision exponent.
-
-_FPunderflow: st r1,r31,0 ;save return address
-#ifdef HANDLER
- bb0 efunf,r12,denorm ;jump to default procedure
- bb1.n destsize,r12,doubleprec ;double precision destination
- set r2,r2,1<underflow> ;set underflow flag in FPSR
-singleprec: or.u r6,r0,0x0c00 ;load exponent adjust 192
- br.n callundhand ;branch to call handler for user handler
- add r12,r6,r12 ;adjust single precision exponent
-doubleprec: or.u r6,r0,0x6000 ;load exponent adjust 1536
- add r12,r6,r12 ;adjust double precision exponent
-callundhand: bsr _handler ;call handler for user handler
- br Ureturn ;return from subroutine
-#endif
-
-;Now the floating point number, which has an exponent smaller than what
-;IEEE allows, must be denormalized. Denormalization is done by calculating
-;the difference between a denormalized exponent and an underflow exponent and
-;shifting the mantissa by that amount. A one may need to be subtracted from
-;the LSB if a one was added during rounding.
-;r9 is used to contain the guard, round, sticky, and an inaccuracy bit in
-;case some bits were shifted off the mantissa during denormalization.
-;r9 will contain: bit 4 -- new addone if one added during rounding
-; after denormalization
-; bit 3 -- inaccuracy flag caused by denormalization
-; or pre-denormalization inexactness
-; bit 2 -- guard bit of result
-; bit 1 -- round bit of result
-; bit 0 -- sticky bit of result
-
-denorm: bb1.n destsize,r12,Udouble ;denorm for double
- extu r9,r10,3<26> ;load r9 with grs
-Usingle: mak r5,r10,21<3> ;extract high 21 bits of mantissa
- extu r6,r11,3<29> ;extract low 3 bits of mantissa
- or r11,r5,r6 ;form 24 bits of mantissa
-
-;See if the addone bit is set and unround if it is.
- bb0.n 25,r10,nounrounds ;do not unround if addone bit clear
- extu r6,r12,12<20> ;extract signed exponent from IMPCR
-unrounds: subu r11,r11,1 ;subtract 1 from mantissa
-;If the hidden bit is cleared after subtracting the one, then the one added
-;during the rounding must have propagated through the mantissa. The exponent
-;will need to be decremented.
- bb1 23,r11,nounrounds ;if hidden bit is set,then exponent does
- ;not need to be decremented
-decexps: sub r6,r6,1 ;decrement exponent 1
- set r11,r11,1<23> ;set the hidden bit
-
-;For both single and double precision, there are cases where it is easier
-;and quicker to make a special case. Examples of this are if the shift
-;amount is only 1 or 2, or all the mantissa is shifted off, or all the
-;mantissa is shifted off and it is still shifting, or, in the case of
-;doubles, if the shift amount is around the boundary of MANTLO and MANTHI.
-
-nounrounds: or r8,r0,lo16(0x00000f81) ;load r8 with -127 in decimal
- ;for lowest 12 bits
- sub r7,r8,r6 ;find difference between two exponents,
- ;this amount is the shift amount
- cmp r6,r7,3 ;check to see if r7 contains 3 or more
- bb1 ge,r6,threesing ;br to code that handles shifts of >=3
- cmp r6,r7,2 ;check to see if r7 contains 2
- bb1 eq,r6,twosing ;br to code that handles shifts of 2
-one: rot r9,r9,0<1> ;rotate roundoff register once, this places
- ;guard in round and round in sticky
- bb0 31,r9,nosticky1s;do not or round and sticky if sticky is
- ;0, this lost bit will be cleared later
- set r9,r9,1<0> ;or round and sticky
-nosticky1s: bb0 0,r11,guardclr1s ;do not set guard bit if LSB = 0
- set r9,r9,1<2> ;set guard bit
-guardclr1s: extu r11,r11,31<1> ;shift mantissa right 1
- br.n round ;round result
- mak r9,r9,3<0> ;clear bits lost during rotation
-
-twosing: rot r9,r9,0<2> ;rotate roundff register twice, this places
- ;guard in sticky
- bb0 30,r9,nosticky2s ;do not or guard and sticky if stick is 0
- ;this lost bit will be cleared later
- br.n noround2s ;skip or old guard and old round if old
- ;sticky set
- set r9,r9,1<0> ;or guard and sticky
-nosticky2s: bb0 31,r9,noround2s ;do not or guard and round if round is 0
- ;this lost bit will be cleared later
- set r9,r9,1<0> ;or guard and round
-noround2s: bb0 0,r11,roundclr2s ;do not set round bit if LSB = 0
- set r9,r9,1<1> ;set round bit
-roundclr2s: bb0 1,r11,guardclr2s ;do not set guard bit if LSB + 1 = 0
- set r9,r9,1<2> ;set guard bit
-guardclr2s: extu r11,r11,30<2> ;shift mantissa right 2
- br.n round ;round result
- mak r9,r9,3<0> ;clear bits lost during rotation
-
-threesing: bb1 0,r9,noguard3s ;check sticky initially
- ;sticky is set, forget most of the oring
-nosticky3s: bb0 1,r9,noround3s ;check round initially, do not set sticky
- br.n noguard3s ;forget most of the rest of oring
- set r9,r9,1<0> ;if round is clear,set sticky if round set
-noround3s: bb0.n 2,r9,noguard3s ;check guard initially, do not set sticky
- clr r9,r9,2<1> ;clear the original guard and round for when
- ;you get to round section
- set r9,r9,1<0> ;if guard is clear,set sticky if guard set
-noguard3s: cmp r6,r7,23 ;check if # of shifts is <=23
- bb1 gt,r6,s24 ;branch to see if shifts = 24
- sub r6,r7,2 ;get number of bits to check for sticky
- mak r6,r6,5<5> ;shift width into width field
- mak r8,r11,r6 ;mask off shifted bits -2
- ff1 r8,r8 ;see if r8 has any ones
- bb1 5,r8,nostky23 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky23: or r8,r0,34 ;start code to get new mantissa plus two
- ;extra bits for new round and new guard bits
- subu r8,r8,r7
- mak r8,r8,5<5> ;shift field width into second five bits
- extu r6,r6,5<5> ;shift previous shifted -2 into offset field
- or r6,r6,r8 ;complete field
- extu r11,r11,r6 ;form new mantissa with two extra bits
-
- bb0 0,r11,nornd3s ;do not set new round bit
- set r9,r9,1<1> ;set new round bit
-nornd3s: bb0 1,r11,nogrd3s ;do not set new guard bit
- set r9,r9,1<2> ;set new guard bit
-nogrd3s: br.n round ;round mantissa
- extu r11,r11,30<2> ;shift off remaining two bits
-
-s24: cmp r6,r7,24 ;check to see if # of shifts is 24
- bb1 gt,r6,s25 ;branch to see if shifts = 25
- bb1 0,r9,nostky24 ;skip checking if old sticky set
- extu r8,r11,22<0> ;prepare to check bits that will be shifted
- ;into the sticky
- ff1 r8,r8 ;see if there are any 1''s
- bb1 5,r8,nostky24 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky24: bb0 22,r11,nornd24 ;do not set new round bit
- set r9,r9,1<1> ;set new round bit
-nornd24: set r9,r9,1<2> ;set new guard bit,this is hidden bit
- br.n round ;round mantissa
- or r11,r0,r0 ;clear r11, all of mantissa shifted off
-
-s25: cmp r6,r7,25 ;check to see if # of shifts is 25
- bb1 gt,r6,s26 ;branch to execute for shifts => 26
- bb1 0,r9,nostky25 ;skip checking if old sticky set
- extu r8,r11,23<0> ;prepare to check bits that will be shifted
- ;into the sticky
- ff1 r8,r8 ;see if there are any 1''s
- bb1 5,r8,nostky25 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky25: set r9,r9,1<1> ;set new round bit,this is hidden bit
- clr r9,r9,1<2> ;clear guard bit since nothing shifted in
- br.n round ;round and assemble result
- or r11,r0,r0 ;clear r11, all of mantissa shifted off
-
-s26: set r9,r9,1<0> ;set sticky bit,this contains hidden bit
- clr r9,r9,2<1> ;clear guard and round bits since nothing
- ;shifted in
- br.n round ;round and assemble result
- or r11,r0,r0 ;clear mantissa
-
-Udouble: mak r5,r10,21<0> ;extract upper bits of mantissa
- bb0.n 25,r10,nounroundd ;do not unround if addone bit clear
- extu r6,r12,12<20>;extract signed exponenet from IMPCR
-unroundd: or r8,r0,1
- subu.co r11,r11,r8 ;subtract 1 from mantissa
- subu.ci r5,r5,r0 ;subtract borrow from upper word
- bb1 20,r5,nounroundd ;if hidden bit is set, then exponent does
- ;not need to be decremented
-decexpd: sub r6,r6,1 ;decrement exponent 1
- set r5,r5,1<20> ;set the hidden bit
-
-nounroundd: or r8,r0,lo16(0x00000c01) ;load r8 with -1023 in decimal
- ;for lowest 12 bits
- sub r7,r8,r6 ;find difference between two exponents,
- ;this amount is the shift amount
- cmp r6,r7,3 ;check to see if r7 contains 3 or more
- bb1 ge,r6,threedoub ;br to code that handles shifts of >=3
- cmp r6,r7,2 ;check to see if r7 contains 2
- bb1 eq,r6,twodoub ;br to code that handles shifts of 2
-
-onedoub: rot r9,r9,0<1> ;rotate roundoff register once, this places
- ;guard in round and round in sticky
- bb0 31,r9,nosticky1d;do not or round and sticky if sticky is 0
- ;this lost bit will be cleared later
- set r9,r9,1<0> ;or old round and old sticky into new sticky
-nosticky1d: bb0 0,r11,guardclr1d ;do not set new guard bit if old LSB = 0
- set r9,r9,1<2> ;set new guard bit
-guardclr1d: extu r11,r11,31<1> ;shift lower mantissa over 1
- mak r6,r5,1<31> ;shift off low bit of high mantissa
- or r11,r6,r11 ;load high bit onto lower mantissa
- extu r5,r5,20<1> ;shift right once upper 20 bits of mantissa
- br.n round ;round mantissa and assemble result
- mak r9,r9,3<0> ;clear bits lost during rotation
-
-twodoub: rot r9,r9,0<2> ;rotate roundoff register twice, this places
- ;old guard into sticky
- bb0 30,r9,nosticky2d ;do not or old guard and old sticky if
- ;old sticky is 0
- br.n noround2d ;skip or of old guard and old round if old
- ;sticky set
- set r9,r9,1<0> ;or old guard and old sticky into new sticky
-nosticky2d: bb0 31,r9,noround2d ;do not or old guard and old round if
- ;old round is 0
- set r9,r9,1<0> ;or old guard and old round into new sticky
-noround2d: bb0 0,r11,roundclr2d ;do not set round bit if old LSB = 0
- set r9,r9,1<1> ;set new round bit
-roundclr2d: bb0 1,r11,guardclr2d ;do not set guard bit if old LSB + 1 = 0
- set r9,r9,1<2> ;set new guard bit
-guardclr2d: extu r11,r11,30<2> ;shift lower mantissa over 2
- mak r6,r5,2<30> ;shift off low bits of high mantissa
- or r11,r6,r11 ;load high bit onto lower mantissa
- extu r5,r5,19<2> ;shift right twice upper 19 bits of mantissa
- br.n round ;round mantissa and assemble result
- mak r9,r9,3<0> ;clear bits lost during rotation
-
-threedoub: bb1 0,r9,noguard3d ;checky sticky initially
- ;sticky is set, forget most of rest of oring
-nosticky3d: bb0 1,r9,noround3d ;check old round, do not set sticky if
- ;old round is clear, set otherwise
- br.n noguard3d ;sticky is set, forget most of rest of oring
- set r9,r9,1<0> ;set sticky if old round is set
-noround3d: bb0 2,r9,noguard3d ;check old guard, do not set sticky if 0
- clr r9,r9,2<1> ;clear the original guard and round for when
- ;you get to round section
- set r9,r9,1<0> ;set sticky if old guard is set
-noguard3d: cmp r6,r7,32 ;do I need to work with a 1 or 2 word mant.
- ;when forming sticky, round and guard
- bb1 gt,r6,d33 ;jump to code that handles 2 word mantissas
- sub r6,r7,2 ;get number of bits to check for sticky
- mak r6,r6,5<5> ;shift width into width field
- mak r8,r11,r6 ;mask off shifted bits -2
- ff1 r8,r8 ;see if r8 has any ones
- bb1 5,r8,nostky32 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky32: or r8,r0,34 ;start code to get new mantissa plus two
- ;extra bits for new round and new guard bits,
- ;the upper word bits will be shifted after
- ;the round and guard bits are handled
- subu r8,r8,r7
- mak r8,r8,5<5> ;shift field width into second five bits
- extu r6,r6,5<5> ;shift previous shifted -2 into offset field
- or r6,r6,r8 ;complete bit field
- extu r11,r11,r6 ;partially form new low mantissa with 2 more
- ;bits
- bb0 0,r11,nornd32d ;do not set new round bit
- set r9,r9,1<1> ;set new round bit
-nornd32d: bb0 1,r11,nogrd32d ;do not set new guard bit
- set r9,r9,1<2> ;set new guard bit
-nogrd32d: extu r11,r11,30<2> ;shift off remaining two bits
- mak r6,r7,5<5> ;shift field width into second 5 bits, if the
- ;width is 32, then these bits will be 0
- or r8,r0,32 ;load word length into r8
- sub r8,r8,r7 ;form offset for high bits moved to low word
- or r6,r6,r8 ;form complete bit field
- mak r6,r5,r6 ;get shifted bits of high word
- or r11,r6,r11 ;form new low word of mantissa
- bcnd ne0,r8,regular33 ;do not adjust for special case of r8
- br.n round ;containing zeros, which would cause
- or r5,r0,r0 ;all of the bits to be extracted under
- ;the regular method
-regular33: mak r6,r7,5<0> ;place lower 5 bits of shift into r6
- mak r8,r8,5<5> ;shift r8 into width field
- or r6,r6,r8 ;form field for shifting of upper bits
- br.n round ;round and assemble result
- extu r5,r5,r6 ;form new high word mantissa
-
-d33: cmp r6,r7,33 ;is the number of bits to be shifted is 33?
- bb1 gt,r6,d34 ;check to see if # of bits is 34
- bb1 0,r9,nostky33 ;skip checking if old sticky set
- mak r6,r11,31<0> ;check bits that will be shifted into sticky
- ff1 r8,r8 ;check for ones
- bb1 5,r8,nostky33 ;do not set sticky if there are no ones
- set r9,r9,1<0> ;set new sticky bit
-nostky33: bb0 31,r11,nornd33 ;do not set round if bit is not a 1
- set r9,r9,1<1> ;set new round bit
-nornd33: bb0 0,r5,nogrd33 ;do not set guard bit if bit is not a 1
- set r9,r9,1<2> ;set new guard bit
-nogrd33: extu r11,r5,31<1> ;shift high bits into low word
- br.n round ;round and assemble result
- or r5,r0,r0 ;clear high word
-
-d34: cmp r6,r7,34 ;is the number of bits to be shifted 34?
- bb1 gt,r6,d35 ;check to see if # of bits is >= 35
- bb1 0,r9,nostky34 ;skip checking if old sticky set
- ff1 r8,r11 ;check bits that will be shifted into sticky
- bb1 5,r8,nostky34 ;do not set sticky if there are no ones
- set r9,r9,1<0> ;set new sticky bit
-nostky34: bb0 0,r5,nornd34 ;do not set round if bit is not a 1
- set r9,r9,1<1> ;set new round bit
-nornd34: bb0 1,r5,nogrd34 ;do not set guard bit if bit is not a 1
- set r9,r9,1<2> ;set new guard bit
-nogrd34: extu r11,r5,30<2> ;shift high bits into low word
- br.n round ;round and assemble result
- or r5,r0,r0 ;clear high word
-
-d35: cmp r6,r7,52 ;see if # of shifts is 35 <= X <= 52
- bb1 gt,r6,d53 ;check to see if # of shifts is 52
- bb1.n 0,r9,nostky35 ;skip checking if old sticky set
- sub r7,r7,34 ;subtract 32 from # of shifts so that opera-
- ;tions can be done on the upper word, and
- ;then subtract two more checking guard and
- ;sticky bits
- ff1 r8,r11 ;see if lower word has a bit for sticky
- bb1 5,r8,stkycheck35 ;see if upper word has any sticky bits
- br.n nostky35 ;quit checking for sticky
- set r9,r9,1<0> ;set sticky bit
-stkycheck35: mak r6,r7,5<5> ;place width into width field
- mak r8,r5,r6 ;mask off shifted bits - 2
- ff1 r8,r8 ;see if r8 has any ones
- bb1 5,r8,nostky35 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky35: or r8,r0,32 ;look at what does not get shifted off plus
- ;round and sticky, remember that the r7 value
- ;was adjusted so that it did not include
- ;new round or new sticky in shifted off bits
- subu r8,r8,r7 ;complement width
- mak r8,r8,5<5> ;shift width into width field
- or r8,r7,r8 ;add offset field
- extu r11,r5,r8 ;extract upper bits into low word
- bb0 0,r11,nornd35 ;do not set new round bit
- set r9,r9,1<1> ;set new round bit
-nornd35: bb0 1,r11,nogrd35 ;do not set new guard bit
- set r9,r9,1<2> ;set new guard bit
-nogrd35: extu r11,r11,30<2> ;shift off remaining guard and round bits
- br.n round ;round and assemble result
- or r5,r0,r0 ;clear high word
-
-d53: cmp r6,r7,53 ;check to see if # of shifts is 53
- bb1 gt,r6,d54 ;branch to see if shifts = 54
- bb1 0,r9,nostky53 ;skip checking if old sticky set
- ff1 r8,r11 ;see if lower word has a bit for sticky
- bb1 5,r8,stkycheck53 ;see if upper word has any sticky bits
- br.n nostky53 ;quit checking for sticky
- set r9,r9,1<0> ;set sticky bit
-stkycheck53: mak r6,r5,19<0> ;check bits that are shifted into sticky
- ff1 r8,r6 ;see if r6 has any ones
- bb1 5,r8,nostky53 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky53: bb0 19,r5,nornd53 ;do not set new round bit
- set r9,r9,1<1> ;set new round bit
-nornd53: set r9,r9,1<2> ;set new guard bit,this is hidden bit
- or r5,r0,r0 ;clear high word
- br.n round ;round and assemble result
- or r11,r0,r0 ;clear low word
-
-d54: cmp r6,r7,54 ;check to see if # of shifts is 54
- bb1 gt,r6,d55 ;branch to execute for shifts =>55
- bb1 0,r9,nostky54 ;skip checking if old sticky set
- ff1 r8,r11 ;see if lower word has a bit for sticky
- bb1 5,r8,stkycheck54 ;see if upper word has any sticky bits
- br.n nostky54 ;quit checking for sticky
- set r9,r9,1<0> ;set sticky bit
-stkycheck54: mak r6,r5,20<0> ;check bits that are shifted into sticky
- ff1 r8,r6 ;see if r6 has any ones
- bb1 5,r8,nostky54 ;do not set sticky if no ones found
- set r9,r9,1<0> ;set sticky bit
-nostky54: set r9,r9,1<1> ;set new round bit,this is hidden bit
- clr r9,r9,1<2> ;clear guard bit since nothing shifted in
- or r5,r0,r0 ;clear high word
- br.n round ;round and assemble result
- or r11,r0,r0 ;clear low word
-
-d55: set r9,r9,1<0> ;set new sticky bit,this contains hidden bit
- clr r9,r9,2<1> ;clear guard and round bits since nothing
- ;shifted in
- or r5,r0,r0 ;clear high word
- or r11,r0,r0 ;clear low word
-
-
-;The first item that the rounding code does is see if either guard, round,
-;or sticky is set. If all are clear, then there is no denormalization loss
-;and no need to round, then branch to assemble answer.
-;For rounding, a branch table is set up. The left two most bits are the
-;rounding mode. The third bit is either the LSB of the mantissa or the
-;sign bit, depending on the rounding mode. The three LSB''s are the guard,
-;round and sticky bits.
-
-round: ff1 r8,r9 ;see if there is denormalization loss
- bb1 5,r8,assemble ;no denormalization loss or inexactness
- extu r6,r10,2<modelo> ;extract rounding mode
- bb1.n modehi,r10,signext ;use sign bit instead of LSB
- mak r6,r6,2<4> ;shift over rounding mode
- extu r7,r11,1<0> ;extract LSB
- br.n grs ;skip sign extraction
- mak r7,r7,1<3> ;shift over LSB
-signext: extu r7,r10,1<31> ;extract sign bit
- mak r7,r7,1<3> ;shift sign bit over
-grs: or r6,r6,r7
- or r6,r6,r9 ;or in guard, round, and sticky
- or.u r1,r0,hi16(roundtable) ;form address of branch table
- or r1,r1,lo16(roundtable)
- lda r6,r1[r6] ;scale offset into branch table
- jmp.n r6 ;jump to branch table
- set r9,r9,1<3> ;set inexact flag in r9
-
-roundtable: br noaddone
-r000001: br noaddone
-r000010: br noaddone
-r000011: br noaddone
-r000100: br noaddone
-r000101: br addone
-r000110: br addone
-r000111: br addone
-r001000: br noaddone
-r001001: br noaddone
-r001010: br noaddone
-r001011: br noaddone
-r001100: br addone
-r001101: br addone
-r001110: br addone
-r001111: br addone
-r010000: br noaddone
-r010001: br noaddone
-r010010: br noaddone
-r010011: br noaddone
-r010100: br noaddone
-r010101: br noaddone
-r010110: br noaddone
-r010111: br noaddone
-r011000: br noaddone
-r011001: br noaddone
-r011010: br noaddone
-r011011: br noaddone
-r011100: br noaddone
-r011101: br noaddone
-r011110: br noaddone
-r011111: br noaddone
-r100000: br noaddone
-r100001: br noaddone
-r100010: br noaddone
-r100011: br noaddone
-r100100: br noaddone
-r100101: br noaddone
-r100110: br noaddone
-r100111: br noaddone
-r101000: br noaddone
-r101001: br addone
-r101010: br addone
-r101011: br addone
-r101100: br addone
-r101101: br addone
-r101110: br addone
-r101111: br addone
-r110000: br noaddone
-r110001: br addone
-r110010: br addone
-r110011: br addone
-r110100: br addone
-r110101: br addone
-r110110: br addone
-r110111: br addone
-r111000: br noaddone
-r111001: br noaddone
-r111010: br noaddone
-r111011: br noaddone
-r111100: br noaddone
-r111101: br noaddone
-r111110: br noaddone
-r111111: br noaddone
-
-;Round by adding a one to the LSB of the mantissa.
-addone: or r6,r0,1 ;load a 1 into r6 so that add.co can be used
- add.co r11,r11,r6 ;add a one to the lower word of result
- bb0.n destsize,r12,noaddone ;single result,forget carry
- set r9,r9,1<4> ;indicate that a 1 has been added
- add.ci r5,r5,r0 ;propagate carry into high word
-
-
-;Branch to inexact user handler if there is one.
-
-noaddone:
-#ifdef HANDLER
- bb1.n efinx,r12,modformdef ;branch to modify form for user
- ;handler
- or r2,r2,5 ;set inexact and underflow flags
-#endif
-
-
-;Assemble the result of the denormalization routine for writeback to the
-;destination register. The exponent of a denormalized number is zero,
-;so simply assemble the sign and the new mantissa.
-
-assemble: bb1 destsize,r12,doubassem ;assemble double result
- bb0 sign,r10,exassems ;exit assemble if sign is zero
- set r11,r11,1<sign> ;make result negative
-exassems: br Ureturn ;return from subroutine
-
-doubassem: bb0.n sign,r10,signclr ;do not set sign in r10
- or r10,r5,r0 ;load high word from r5 into r10
- set r10,r10,1<sign> ;high word with sign loaded
-signclr: br Ureturn ;return from subroutine
-
-
-;modfordef modifies the result of denormalization to the input format of
-;the inexact user handler. This input format is the same format that
-;MANTHI, MANTLO, and IMPCR were initially loaded with.
-
-#ifdef HANDLER
-modformdef: clr r12,r12,12<20> ;clear result exponent,IMPCR complete
- clr r10,r10,4<25> ;clear old guard,round,sticky,and addone
- mak r5,r9,3<26> ;make grs field
- bb0.n 4,r9,newaddone ;do not set new addone in MANTHI
- or r10,r5,r10 ;or in new grs field
- set r10,r10,1<25> ;set new addone
-newaddone: bb1.n destsize,r12,moddefd ;branch to handle double precision
- clr r10,r10,21<0> ;clear upper bits of old mantissa
-moddefs: extu r5,r11,20<3> ;extract upper bits
- or r10,r5,r10 ;MANTHI complete
- bsr.n _handler ;execute user handler for inexact
- rot r11,r11,0<3> ;MANTLO complete
- br Ureturn ;return from subroutine
-moddefd: bsr.n _handler ;execute user handler for inexact
- or r10,r5,r10 ;MANTHI complete,r5 should be set to OR
-#endif
-
-
-;Return to fpui.
-
-Ureturn: ld r1,r31,0 ;load return address
- jmp r1 ;return from subroutine
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-;function _FPoverflow --
-;The documentation for this release gives an overall description of this code.
-data
-align 4
-msg2: string "here at line %d, r1 is %x\n\0"
-text
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
-#line 23
- global _FPoverflow
- text
-
-
-;If the overflow user handler bit is not set, then the inexact bit in the
-;FPSR is set, and the inexact user handler bit is checked. If it is set,
-;then the inexact user handler is executed, else the default routine for
-;overflow is executed.
-
-_FPoverflow:
- st r1,r31,0 ;save return address
-#ifdef HANDLER
- set r2,r2,1<overflow> ;set overflow bit in r2 which holds FPSR
- bb1 efovf,r12,hand ;go to user handler if bit set for overflow
- set r2,r2,1<inexact> ;set inexact bit in r2 since overflow bit
- ;in FPCR is not set
- bb0 efinx,r12,nohandler;if userhandler for inexact not set,then
- ;round result
- br callhandler ;branch to user handler for inexact
-
-;Before the overflow user handler is executed, the exponent is modified
-;by subtracting 192 for single precision and 1536 for double precision.
-
-hand: bb1 10,r12,doubleprec ;double precision result
-singleprec: or.u r5,r0,0x0c00 ;load exponent adjust
- br.n callhandler ;prepare to call user handler
- subu r12,r12,r5 ;adjust single precision exponent
-doubleprec: or.u r5,r0,0x6000 ;load exponent adjust
- subu r12,r12,r5 ;adjust double precision exponent
-callhandler: bsr _handler ;branch to common handler routine
- br return ;return from overflow subroutine
-#endif
-
-;Determine which rounding mode to use for the default procedure.
-
-nohandler: bb1 modehi,r10,signed ;mode is either round toward pos. or neg.
- bb0 modelo,r10,OFnearest ;rounding mode is round nearest
- br OFzero ;rounding mode is round zero
-signed: bb0 modelo,r10,OFnegative ;rounding mode is round negative
- br positive ;rounding mode is round positive
-
-
-;In the round toward nearest mode, positive values are rounded to
-;postive infinity and negative values are loaded toward negative infinity.
-;The value for single or double precision is loaded from a data table.
-
-OFnearest:
- bb1.n destsize,r12,neardouble ;branch to neardouble of
- ;double result
- mask.u r5,r10,0x8000 ;mask off sign bit from MANTHI
- or.u r11,r0,hi16(0x7f800000) ;load single infinity constant
- or r11,r11,lo16(0x7f800000)
- br.n return ;return with result
- or r11,r5,r11 ;adjust sign
-neardouble:
- or r11,r0,r0 ;load lower word of infinity
- or.u r10,r0,hi16(0x7ff00000) ;load upper word of infinity
- or r10,r10,lo16(0x7ff00000)
- br.n return ;return with result
- or r10,r5,r10 ;adjust sign
-
-
-;In the round toward zero mode, positive values are rounded to the largest
-;postive finite number and negative values are rounded toward the largest
-;negative finite number.
-;The value for single or double precision is loaded from a data table.
-
-OFzero:
- bb1.n destsize,r12,zerodouble ;branch to zerodouble of
- ;double result
- mask.u r5,r10,0x8000 ;mask off sign bit from MANTHI
- or.u r11,r0,hi16(0x7f7fffff) ;load single finite number constant
- or r11,r11,lo16(0x7f7fffff)
- br.n return ;return with result
- or r11,r5,r11 ;adjust sign
-zerodouble:
- set r11,r0,0<0> ;load lower word of finite number
- or.u r10,r0,hi16(0x7fefffff) ;load upper word of finite number
- or r10,r10,lo16(0x7fefffff)
- br.n return ;return with result
- or r10,r5,r10 ;adjust sign
-
-
-;In the round toward positve mode, positive values are rounded to
-;postive infinity and negative values are loaded toward the largest
-;negative finite number.
-;The value for single or double precision is loaded from a data table.
-
-positive:
- bb1 destsize,r12,posdouble ;branch to section for double result
-possingle:
- bb1 sign,r10,possingleneg ;branch to section for negatives
-possinglepos:
- or.u r11,r0,hi16(0x7f800000) ;load single infinity constant
- br.n return ;return with result
- or r11,r11,lo16(0x7f800000)
-possingleneg:
- or.u r11,r0,hi16(0x7f7fffff) ;load single finite number constant
- or r11,r11,lo16(0x7f7fffff)
- br.n return ;return with result
- set r11,r11,1<sign> ;set sign for negative
-posdouble:
- bb1 sign,r10,posdoubleneg ;branch to negative double results
-posdoublepos:
- or r11,r0,r0 ;load lower word of double infinity
- or.u r10,r0,hi16(0x7ff00000) ;load upper word of infinity
- br.n return ;return with result
- or r10,r10,lo16(0x7ff00000)
-posdoubleneg:
- set r11,r0,0<0> ;load lower word of finite number
- or.u r10,r0,hi16(0x7fefffff) ;load upper word of finite number
- or r10,r10,lo16(0x7fefffff)
- br.n return ;return with result
- set r10,r10,1<sign> ;set sign for negative
-
-
-;In the round toward negative mode, positive values are rounded to the largest
-;postive finite number and negative values are rounded to negative infinity.
-;The value for single or double precision is loaded from a data table.
-
-OFnegative:
- bb1 destsize,r12,negdouble ;branch to section for double result
-negsingle:
- bb1 sign,r10,negsingleneg ;branch to section for negatives
-negsinglepos:
- or.u r11,r0,hi16(0x7f7fffff) ;load single finite number constant
- br.n return ;return with result
- or r11,r11,lo16(0x7f7fffff)
-negsingleneg:
- or.u r11,r0,hi16(0x7f800000) ;load single infinity constant
- or r11,r11,lo16(0x7f800000)
- br.n return ;return with result
- set r11,r11,1<sign> ;set sign for negative
-negdouble:
- bb1 sign,r10,negdoubleneg ;branch to negative double results
-negdoublepos:
- set r11,r0,0<0> ;load lower word of finite number
- or.u r10,r0,hi16(0x7fefffff) ;load upper word of finite number
- br.n return ;return with result
- or r10,r10,lo16(0x7fefffff)
-negdoubleneg:
- or r11,r0,r0 ;load lower word of double infinity
- or.u r10,r0,hi16(0x7ff00000) ;load upper word of infinity
- or r10,r10,lo16(0x7ff00000)
- set r10,r10,1<sign> ;set sign for negative
-
-return:
- ld r1,r31,0 ;ld return address
- jmp r1 ;return from subroutine
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- text
-
-;If either S1 or S2 is a signalling NaN, then set the invalid operation
-;bit of the FPSR. If the invalid operation user handler flag is set and
-;then NaN is signalling, then branch to the handler routine to go to the
-;user handler.
-;If S1 is the only NaN or one of two NaN''s, then write
-;a quiet S1 to the result. A signalling NaN must be made quiet before
-;it can be written, but a signalling S2 is not modified in this routine
-;if S1 is a NaN.
-
-LABEL(_NaN)
- bb0.n s1nan,r12,S2sigcheck ;S1 is not a NaN
- st r1,r31,0 ;save return address
- bb1 sigbit,r5,S2sigcheck ;S1 is not a signaling NaN
- set r2,r2,1<oper> ;set invalid operation bit in FPSR
-#ifdef JEFF_DEBUGxxxxxxx
- /*
- * Generate a signal to the offending process.
- * This uses hardcoded constants from mach/exception.h
- * and mach/machine/exception.h.
- */
- ldcr r2, cr17 /* first arg: current_thread() */
- or r3, r0, 3 /* second arg: EXC_ARITHMETIC */
- or r4, r0, 3 /* third arg: EXC_M88K_FLOAT_P */
- or r5, r0, r0
- subu r31, r31, 48
- bsr.n _thread_doexception
- st r1, r31, 44
- ld r1, r31, 44
- br.n FPnan_return
- addu r31, r31, 48
-#endif
-#ifdef HANDLER
- bb0 oper,r3,S1nohandler ;branch if no user handler
- bsr _handler ;branch to handler
- br FPnan_return
-_LABEL(S1nohandler)
-#endif
- br.n S1write ;FPSR bit already set, S1 is made quiet,
- ;and since we always write S1 if it is a
- ;NaN, write S1 and skip rest of routine
- set r5,r5,1<sigbit> ;make S1 a quiet NaN
-
-_LABEL(S2sigcheck)
- bb0 s2nan,r12,S1write ;S2 is not a NaN
- bb1 sigbit,r7,S1write ;S2 is not a signaling NaN
- set r2,r2,1<oper> ;set invalid operation bit in FPSR
-#ifdef HANDLER
- bb0 oper,r3,S2nohandler ;branch if no user handler
- bsr _handler ;branch to handler
- br FPnan_return
-#endif
-
-_LABEL(S2nohandler)
- set r7,r7,1<sigbit> ;make S2 a quiet NaN
-
-
-;Write a single or double precision quiet NaN unless the opeation is FCMP.
-;If the operation is FCMP, then set the not comparable bit in the result.
-
-_LABEL(S1write)
- bb0 s1nan,r12,S2write ;do not write S1 if it is not a NaN
- extu r10,r9,5<11> ;extract opcode
- cmp r11,r10,FCMPop ;compare to FCMP
- bb1 ne,r11,S1noFCMP ;operation is not FCMP
- set r6,r0,1<nc> ;set the not comparable bit
- br.n FPnan_return ;return from subroutine
- set r6,r6,1<ne> ;set the not equal bit
-_LABEL(S1noFCMP)
- bb1.n dsize,r9,wrdoubS1 ;double destination
- set r5,r5,11<20> ;set all exponent bits to 1
-;The single result will be formed the same way whether S1 is a single or double
-_LABEL(wrsingS1)
- mak r10,r5,28<3> ;wipe out extra exponent bits
- extu r11,r6,3<29> ;get lower three bits of mantissa
- or r10,r10,r11 ;combine all of result except sign
- clr r6,r5,31<0> ;clear all but sign
- br.n FPnan_return ;return from function
- or r6,r6,r10 ;form result
-
-_LABEL(wrdoubS1)
-;;;;;; bb1 s1size,r9,wrdoubS1d ;write double source to double dest.
-/* took out the above instruction -- don't see why it's there.... jfriedl */
-_LABEL(wrdoubS1s)
- set r6,r6,29<0> ;set extra bits of lower word
-_LABEL(wrdoubS1d)
- br FPnan_return ;no modification necessary for writing
- ;double to double, so return from function
-
-_LABEL(S2write)
- extu r10,r9,5<11> ;extract opcode
- cmp r11,r10,FCMPop ;compare to FCMP
- bb1.n ne,r11,S2noFCMP ;operation is not FCMP
- set r7,r7,11<20> ;set all exponent bits to 1
- set r6,r0,1<nc> ;set the not comparable bit
- br.n FPnan_return ;return from subroutine
- set r6,r6,1<ne> ;set the not equal bit
-_LABEL(S2noFCMP)
- bb1.n dsize,r9,wrdoubS2 ;double destination
- /*
- * In the original, the ".n" above and the "set r5..." below
- * were omitted here. Since they're in the S1 stuff above,
- * and since this isn't working right now (r5 isn't being set
- * to it's part of the nan), I'll try this...
- * jfriedl Dec 1, 1989
- */
- set r5,r5,11<20> ;set all exponent bits to 1
-;The single result will be formed the same way whether S1 is a single or double
-_LABEL(wrsingS2)
- mak r10,r7,28<3> ;wipe out extra exponent bits
- extu r11,r8,3<29> ;get lower three bits of mantissa
- or r10,r10,r11 ;combine all of result except sign
- clr r6,r7,31<0> ;clear all but sign
- br.n FPnan_return ;return from function
- or r6,r6,r10 ;form result
-
-_LABEL(wrdoubS2)
-
-;;;; bb1 s2size,r9,FPnan_return ;write double source to double dest.
- /*
- * I took out the above branch because I just don't see how it
- * makes sense. jfriedl Dec 1, '89
- */
-_LABEL(wrdoubS2s)
- set r6,r8,29<0> ;set extra bits of lower word
-
-
-;Return from this subroutine with the result.
-
-_LABEL(FPnan_return)
- ;no modification necessary for writing
- ;double to double, so return from function
- ld r1,r31, 0 ;retrieve return address
- jmp r1 ;return from function
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-;function _infinity --
-;See the documentation of this release for an overall description of this
-;code.
-
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- global _infinity
- text
-
-;Extract the opcode, compare to a constant, and branch to the code
-;for the instruction.
-
-_infinity: extu r10,r9,5<11> ;extract opcode
- cmp r11,r10,FADDop ;compare to FADD
- bb1.n eq,r11,FADD ;operation is FADD
- st r1,r31,0 ;save return address
- cmp r11,r10,FSUBop ;compare to FSUB
- bb1 eq,r11,FSUB ;operation is FSUB
- cmp r11,r10,FCMPop ;compare to FCMP
- bb1 eq,r11,FCMP ;operation is FCMP
- cmp r11,r10,FMULop ;compare to FMUL
- bb1 eq,r11,FMUL ;operation is FMUL
- cmp r11,r10,FDIVop ;compare to FDIV
- bb1 eq,r11,FDIV ;operation is FDIV
-; cmp r11,r10,FSQRTop;compare to FSQRT
-; bb1 eq,r11,FSQRT ;operation is FSQRT
- cmp r11,r10,INTop ;compare to INT
- bb1 eq,r11,FP_inf_overflw ;operation is INT
- cmp r11,r10,NINTop ;compare to NINT
- bb1 eq,r11,FP_inf_overflw ;operation is NINT
- cmp r11,r10,TRNCop ;compare to TRNC
- bb1 eq,r11,FP_inf_overflw ;operation is TRNC
-
-
-;Adding infinities of opposite signs will cause an exception,
-;but all other operands will result in a correctly signed infinity.
-
-FADD: bb0 s1inf,r12,addS2write ;branch if S1 not infinity
- bb0 s2inf,r12,addS1write ;S2 is not inf., so branch to write S1
- bb1 sign,r5,addS1neg ;handle case of S1 negative
-addS1pos: bb1 sign,r7,excpt ;adding infinities of different signs
- ;causes an exception
- br poswrinf ;branch to write positive infinity
-addS1neg: bb0 sign,r7,excpt ;adding infinities of different signs
- ;causes an exception
- br negwrinf ;branch to write negative infinity
-addS1write: bb0 sign,r5,poswrinf ;branch to write positive infinity
- br negwrinf ;branch to write negative infinity
-addS2write: bb0 sign,r7,poswrinf ;branch to write positive infinity
- br negwrinf ;branch to write negative infinity
-
-
-;Subtracting infinities of the same sign will cause an exception,
-;but all other operands will result in a correctly signed infinity.
-
-FSUB: bb0 s1inf,r12,subS2write ;branch if S1 not infinity
- bb0 s2inf,r12,subS1write ;S2 is not inf., so branch to write S1
- bb1 sign,r5,subS1neg ;handle case of S1 negative
-subS1pos: bb0 sign,r7,excpt ;subtracting infinities of the same sign
- ;causes an exception
- br poswrinf ;branch to write positive infinity
-subS1neg: bb1 sign,r7,excpt ;subtracting infinities of the same sign
- ;causes an exception
- br negwrinf ;branch to write negative infinity
-subS1write: bb0 sign,r5,poswrinf ;branch to write positive infinity
- br negwrinf ;branch to write negative infinity
-subS2write: bb1 sign,r7,poswrinf ;branch to write positive infinity
- br negwrinf ;branch to write negative infinity
-
-
-;Compare the operands, at least one of which is infinity, and set the
-;correct bits in the destination register.
-
-FCMP: bb0.n s1inf,r12,FCMPS1f ;branch for finite S1
- set r4,r0,1<cp> ;since neither S1 or S2 is a NaN, set cp
-FCMPS1i: bb1 sign,r5,FCMPS1ni ;branch to negative S1i
-FCMPS1pi: bb0 s2inf,r12,FCMPS1piS2f ;branch to finite S2 with S1pi
-FCMPS1piS2i: bb1 sign,r7,FCMPS1piS2ni ;branch to negative S2i with S1pi
-FCMPS1piS2pi: set r4,r4,1<eq> ;set eq bit
- set r4,r4,1<le> ;set le bit
- set r4,r4,1<ge> ;set ge bit
- set r4,r4,1<ib> ;set ib bit
- br.n move ;return from subroutine
- set r4,r4,1<ob> ;set ob bit
-FCMPS1piS2ni: set r4,r4,1<ne> ;set ne bit
- set r4,r4,1<gt> ;set gt bit
- br.n move ;return from subroutine
- set r4,r4,1<ge> ;set ge bit
-FCMPS1piS2f: set r4,r4,1<ne> ;set ne bit
- set r4,r4,1<gt> ;set gt bit
- bsr.n _zero ;see if any of the operands are zero
- set r4,r4,1<ge> ;set ge bit
- bb0 s2zero,r12,FCMPS1piS2nz ;check for negative if s2 not zero
- set r4,r4,1<ou> ;set ou bit
- br.n move
- set r4,r4,1<ob> ;set ob bit
-FCMPS1piS2nz: bb1 sign,r7,move ;return from subroutine if s2 is neg.
-FCMPS1piS2pf: set r4,r4,1<ou> ;set ou bit
- br.n move ;return from subroutine
- set r4,r4,1<ob> ;set ob bit
-FCMPS1ni: bb0 s2inf,r12,FCMPS1niS2f ;branch to finite S2 with S1ni
-FCMPS1niS2i: bb1 sign,r7,FCMPS1niS2ni ;branch to negative S2i with S1ni
-FCMPS1niS2pi: set r4,r4,1<ne> ;set eq bit
- set r4,r4,1<le> ;set le bit
- set r4,r4,1<lt> ;set lt bit
- set r4,r4,1<ou> ;set ou bit
- br.n move ;return from subroutine
- set r4,r4,1<ob> ;set ob bit
-FCMPS1niS2ni: set r4,r4,1<eq> ;set eq bit
- set r4,r4,1<le> ;set le bit
- br.n move ;return from subroutine
- set r4,r4,1<ge> ;set ge bit
-FCMPS1niS2f: set r4,r4,1<ne> ;set eq bit
- set r4,r4,1<le> ;set le bit
- bsr.n _zero ;see if any of the operands are zero
- set r4,r4,1<lt> ;set lt bit
- bb0 s2zero,r12,FCMPS1niS2nz ;branch if s2 is not zero
- set r4,r4,1<ou> ;set ou bit
- br.n move
- set r4,r4,1<ob> ;set ob bit
-FCMPS1niS2nz: bb1 sign,r7,move ;return from subroutine if s2 is neg.
- set r4,r4,1<ou> ;set ou bit
- br.n move ;return from subroutine
- set r4,r4,1<ob> ;set ob bit
-FCMPS1f: bb1 sign,r5,FCMPS1nf ;branch to negative S1f
-FCMPS1pf: bb1.n sign,r7,FCMPS1pfS2ni ;branch to negative S2i with S1pf
- set r4,r4,1<ne> ;set ne bit
-FCMPS1pfS2pi: set r4,r4,1<le> ;set le bit
- set r4,r4,1<lt> ;set lt bit
- bsr.n _zero
- set r4,r4,1<ib> ;set ib bit
- bb0 s1zero,r12,FCMPS1pfS2pinozero
-FCMPS1pfS2pizero: br.n move
- set r4,r4,1<ob> ;set ob bit
-FCMPS1pfS2pinozero: br.n move
- set r4,r4,1<in> ;set in bit
-FCMPS1pfS2ni: set r4,r4,1<gt> ;set gt bit
- br.n move ;return from subroutine
- set r4,r4,1<ge> ;set ge bit
-FCMPS1nf: bb1.n sign,r7,FCMPS1nfS2ni ;branch to negative S2i with S1nf
- set r4,r4,1<ne> ;set ne bit
- set r4,r4,1<le> ;set gt bit
- set r4,r4,1<lt> ;set ge bit
- bsr.n _zero ;see which of the operands are zero
- set r4,r4,1<ob> ;set ob bit
- bb0 s1zero,r12,FCMPS1nfS2pinozero ;no ls and lo
-FCMPS1nfS2pizero: br.n move
- set r4,r4,1<ib> ;set ib bit
-FCMPS1nfS2pinozero: br.n move
- set r4,r4,1<ou> ;set ou bit
-FCMPS1nfS2ni: set r4,r4,1<gt> ;set gt bit
- set r4,r4,1<ge> ;set ge bit
-
-move: br.n inf_return ;return from subroutine
- or r6,r0,r4 ;transfer answer to r6
-
-
-;Multiplying infinity and zero causes an exception, but all other
-;operations produce a correctly signed infinity.
-
-FMUL: bsr _zero ;see if any of the operands are zero
- bb1 s1zero,r12,excpt ;infinity X 0 causes an exception
- bb1 s2zero,r12,excpt ;infinity X 0 causes an exception
- bb1 sign,r5,FMULS1neg ;handle negative cases of S1
- bb0 sign,r7,poswrinf ;+ X + = +
- br negwrinf ;+ X - = -
-FMULS1neg: bb1 sign,r7,poswrinf ;- X - = +
- br negwrinf ;- X + = -
-
-
-;Dividing infinity by infinity causes an exception, but dividing
-;infinity by a finite yields a correctly signed infinity, and
-;dividing a finite by an infinity produces a correctly signed zero.
-
-FDIV: bb1 s1inf,r12,FDIVS1inf ;handle case of S1 being infinity
- bb1 sign,r5,FDIVS1nf ;handle cases of S1 being neg. non-inf.
- bb1 sign,r7,FDIVS1pfS2mi ;handle case of negative S2
-FDIVS1pfS2pi: br poswrzero ;+f / +inf = +0
-FDIVS1pfS2mi: br negwrzero ;+f / -inf = -0
-FDIVS1nf: bb1 sign,r7,FDIVS1nfS2mi ;handle case of negative S2
-FDIVS1nfS2pi: br negwrzero ;-f / +inf = -0
-FDIVS1nfS2mi: br poswrzero ;-f / -inf = +0
-FDIVS1inf: bb1 s2inf,r12,excpt ;inf / inf = exception
- bb1 sign,r5,FDIVS1mi ;handle cases of S1 being neg. inf.
- bb1 sign,r7,FDIVS1piS2nf ;handle case of negative S2
-FDIVS1piS2pf: br poswrinf ;+inf / +f = +inf
-FDIVS1piS2nf: br negwrinf ;+inf / -f = -inf
-FDIVS1mi: bb1 sign,r7,FDIVS1miS2nf ;handle case of negative S2
-FDIVS1miS2pf: br negwrinf ;-inf / +f = -inf
-FDIVS1miS2nf: br poswrinf ;-inf / -f = +inf
-
-
-;The square root of positive infinity is positive infinity,
-;but the square root of negative infinity is a NaN
-
-;FSQRT: bb0 sign,r7,poswrinf ;write sqrt(inf) = inf
-; br excpt ;write sqrt(-inf) = NaN
-
-excpt:
- set r2,r2,1<oper> ;set invalid operation bit of FPSR
-#ifdef HANDLER
- bb0 oper,r3,nohandler ;branch if no user handler
- bsr _handler ;branch to interface with user handler
- br inf_return ;return from function
-nohandler:
-#endif
- set r5,r0,0<0> ;write NaN into r5
- br.n inf_return ;return from subroutine
- set r6,r0,0<0> ;write NaN into r6, writing NaN''s into
- ;both of these registers is quicker than
- ;checking for single or double precision
-
-
-;Write positive infinity of the correct precision
-
-poswrinf: bb1 dsize,r9,poswrinfd ;branch to write double precision inf.
- br.n inf_return ;return from subroutine
- or.u r6,r0,0x7f80 ;load r6 with single precision pos inf.
-poswrinfd: or.u r5,r0,0x7ff0 ;load double precision pos inf.
- br.n inf_return ;return from subroutine
- or r6,r0,r0
-
-
-;Write negative infinity of the correct precision
-
-negwrinf: bb1 dsize,r9,negwrinfd ;branch to write double precision inf.
- br.n inf_return ;return from subroutine
- or.u r6,r0,0xff80 ;load r6 with single precision pos inf.
-negwrinfd: or.u r5,r0,0xfff0 ;load double precision pos inf.
- br.n inf_return ;return from subroutine
- or r6,r0,r0
-
-
-;Write a positive zero disregarding precision.
-
-poswrzero: or r5,r0,r0 ;write to both high word and low word now
- br.n inf_return ;it does not matter that both are written
- or r6,r0,r0
-
-
-;Write a negative zero of the correct precision.
-
-negwrzero: or r6,r0,r0 ;clear low word
- bb1 dsize,r9,negwrzerod ;branch to write double precision zero
- br.n inf_return ;return from subroutine
- set r6,r6,1<31> ;set sign bit
-negwrzerod: or r5,r0,r0 ;clear high word
- br.n inf_return ;return from subroutine
- set r5,r5,1<31> ;set sign bit
-
-FP_inf_overflw:
- set r2,r2,1<oper> ;set invalid operand bit
-#ifdef HANDLER
- bb0 oper,r3,nohandlero ;do not go to user handler routine
- bsr _handler ;go to user handler routine
- br inf_return ;return from subroutine
-#endif
-
-nohandlero: bb0.n sign,r7,inf_return ;if positive then return from subroutine
-
- set r6,r6,31<0> ;set result to largest positive integer
- or.c r6,r0,r6 ;negate r6,giving largest negative int.
-
-inf_return: ld r1,r31,0 ;load return address
- jmp r1 ;return from subroutine
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#define FADD denorm_FADD
-#define FSUB denorm_FSUB
-#define FCMP denorm_FCMP
-#define FMUL denorm_FMUL
-#define FDIV denorm_FDIV
-#define NINT denorm_NINT
-#define TRNC denorm_TRNC
-#define return denorm_return
-;function _denorm --
-;See the documentation for this release for an overall description of this
-;code.
-
- global _denorm
- text
-
-;Check to see if either S1 or S2 is a denormalized number. First
-;extract the exponent to see if it is zero, and then check to see if
-;the mantissa is not zero. If the number is denormalized, then set the
-;1 or 0 bit 10 r12.
-
-_denorm: st r1,r31,0 ;save return address
-dnmcheckS1: extu r10,r5,11<20> ;extract exponent
- bcnd ne0,r10,dnmsetS2 ;S1 is not a denorm, so S2 must be
- bb1.n 9,r9,dnmcheckS1d ;S1 is double precision
- mak r10,r5,20<3> ;mak field with only mantissa bits
- ;into final result
-dnmcheckS1s: extu r11,r6,3<29> ;get three low bits of mantissa
- or r10,r10,r11 ;assemble all of the mantissa bits
- bcnd eq0,r10,dnmsetS2 ;S1 is not a denorm, so S2 must be
- br dnmsetS1 ;S1 is a denorm
-
-dnmcheckS1d: or r10,r6,r10 ;or all of mantissa bits
- bcnd eq0,r10,dnmsetS2 ;S1 is not a denorm, so S2 must be
-dnmsetS1: set r12,r12,1<1> ;S1 is a denorm
-
-dnmcheckS2: extu r10,r7,11<20> ;extract exponent
- bcnd ne0,r10,S1form ;S2 is not a denorm
- bb1.n 7,r9,dnmcheckS2d ;S2 is double precision
- mak r10,r7,20<3> ;mak field with only mantissa bits
-dnmcheckS2s: extu r11,r8,3<29> ;get three low bits of mantissa
- or r10,r10,r11 ;assemble all of the mantissa bits
- bcnd eq0,r10,S1form ;S2 is not a denorm
- br dnmsetS2 ;S1 is a denorm
-dnmcheckS2d: or r10,r8,r10 ;or all or mantissa bits
- bcnd eq0,r10,S1form ;S2 is not a denorm
-dnmsetS2: set r12,r12,1<0> ;S2 is a denorm
-
-
-;Since the operations are going to be reperformed with modified denorms,
-;the operands which were initially single precision need to be modified
-;back to single precision.
-
-S1form: bb1 9,r9,S2form ;S1 is double precision, so do not
- ;modify S1 into single format
- mak r11,r5,28<3> ; over final exponent and mantissa
- ;eliminating extra 3 bits of exponent
- extu r6,r6,3<29> ;get low 3 bits of mantissa
- or r11,r6,r11 ;form complete mantissa and exponent
- extu r10,r5,1<31> ;get the 31 bit
- mak r10,r10,1<31> ;place 31 bit 10 correct position
- or r6,r10,r11 ;or 31, exponent, and all of mantissa
-
-S2form: bb1 7,r9,checkop ;S2 is double precision, so do not
- ;modify S2 into single format
- mak r11,r7,28<3> ; over final exponent and mantissa
- ;eliminating extra 3 bits of exponent
- extu r8,r8,3<29> ;get low 3 bits of mantissa
- or r11,r8,r11 ;form complete mantissa and exponent
- extu r10,r7,1<31> ;get the 31 bit
- mak r10,r10,1<31> ;place 31 bit 10 correct position
- or r8,r10,r11 ;or 31, exponent, and all of mantissa
-
-
-;Extract the opcode, compare to a constant, and branch to the code that
-;deals with that opcode.
-
-checkop: extu r10,r9,5<11> ;extract opcode
- cmp r11,r10,0x05 ;compare to FADD
- bb1 2,r11,FADD ;operation is FADD
- cmp r11,r10,0x06 ;compare to FSUB
- bb1 2,r11,FSUB ;operation is FSUB
- cmp r11,r10,0x07 ;compare to FCMP
- bb1 2,r11,FCMP ;operation is FCMP
- cmp r11,r10,0x00 ;compare to FMUL
- bb1 2,r11,FMUL ;operation is FMUL
- cmp r11,r10,0x0e ;compare to FDIV
- bb1 2,r11,FDIV ;operation is FDIV
-; cmp r11,r10,0x0f;compare to FSQRT
-; bb1 2,r11,FSQRT ;operation is FSQRT
- cmp r11,r10,0x09 ;compare to INT
- bb1 2,r11,INT ;operation is INT
- cmp r11,r10,0x0a ;compare to NINT
- bb1 2,r11,NINT ;operation is NINT
- cmp r11,r10,0x0b ;compare to TRNC
- bb1 2,r11,TRNC ;operation is TRNC
-
-
-;For all the following operations, the denormalized number is set to
-;zero and the operation is reperformed the correct destination and source
-;sizes.
-
-FADD: bb0 1,r12,FADDS2dnm ;S1 is not denorm, so S2 must be
- or r5,r0,r0 ;set S1 to zero
- or r6,r0,r0
-FADDS2chk: bb0 0,r12,FADDcalc ;S2 is not a denorm
-FADDS2dnm: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-FADDcalc: bb1 5,r9,FADDdD ;branch for double precision destination
-FADDsD: bb1 9,r9,FADDsDdS1 ;branch for double precision S1
-FADDsDsS1: bb1 7,r9,FADDsDsS1dS2 ;branch for double precision S2
-FADDsDsS1sS2: br.n return ;return from subroutine
- fadd.sss r6,r6,r8 ;add the two sources and place result 10 S1
-FADDsDsS1dS2: br.n return ;return from subroutine
- fadd.ssd r6,r6,r7 ;add the two sources and place result 10 S1
-FADDsDdS1: bb1 7,r9,FADDsDdS1dS2 ;branch for double precision S2
-FADDsDdS1sS2: br.n return ;return from subroutine
- fadd.sds r6,r5,r8 ;add the two sources and place result 10 S1
-FADDsDdS1dS2: br.n return ;return from subroutine
- fadd.sdd r6,r5,r7 ;add the two sources and place result 10 S1
-FADDdD: bb1 9,r9,FADDdDdS1 ;branch for double precision S1
-FADDdDsS1: bb1 7,r9,FADDdDsS1dS2 ;branch for double precision S2
-FADDdDsS1sS2: br.n return ;return from subroutine
- fadd.dss r5,r6,r8 ;add the two sources and place result 10 S1
-FADDdDsS1dS2: br.n return ;return from subroutine
- fadd.dsd r5,r6,r7 ;add the two sources and place result 10 S1
-FADDdDdS1: bb1 7,r9,FADDdDdS1dS2 ;branch for double precision S2
-FADDdDdS1sS2: br.n return ;return from subroutine
- fadd.dds r5,r5,r8 ;add the two sources and place result 10 S1
-FADDdDdS1dS2: br.n return ;return from subroutine
- fadd.ddd r5,r5,r7 ;add the two sources and place result 10 S1
-
-FSUB: bb0 1,r12,FSUBS2dnm ;S1 is not denorm, so S2 must be
- or r5,r0,r0 ;set S1 to zero
- or r6,r0,r0
-FSUBS2chk: bb0 0,r12,FSUBcalc ;S2 is not a denorm
-FSUBS2dnm: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-FSUBcalc: bb1 5,r9,FSUBdD ;branch for double precision destination
-FSUBsD: bb1 9,r9,FSUBsDdS1 ;branch for double precision S1
-FSUBsDsS1: bb1 7,r9,FSUBsDsS1dS2 ;branch for double precision S2
-FSUBsDsS1sS2: br.n return ;return from subroutine
- fsub.sss r6,r6,r8 ;add the two sources and place result 10 S1
-FSUBsDsS1dS2: br.n return ;return from subroutine
- fsub.ssd r6,r6,r7 ;add the two sources and place result 10 S1
-FSUBsDdS1: bb1 7,r9,FSUBsDdS1dS2 ;branch for double precision S2
-FSUBsDdS1sS2: br.n return ;return from subroutine
- fsub.sds r6,r5,r8 ;add the two sources and place result 10 S1
-FSUBsDdS1dS2: br.n return ;return from subroutine
- fsub.sdd r6,r5,r7 ;add the two sources and place result 10 S1
-FSUBdD: bb1 9,r9,FSUBdDdS1 ;branch for double precision S1
-FSUBdDsS1: bb1 7,r9,FSUBdDsS1dS2 ;branch for double precision S2
-FSUBdDsS1sS2: br.n return ;return from subroutine
- fsub.dss r5,r6,r8 ;add the two sources and place result 10 S1
-FSUBdDsS1dS2: br.n return ;return from subroutine
- fsub.dsd r5,r6,r7 ;add the two sources and place result 10 S1
-FSUBdDdS1: bb1 7,r9,FSUBdDdS1dS2 ;branch for double precision S2
-FSUBdDdS1sS2: br.n return ;return from subroutine
- fsub.dds r5,r5,r8 ;add the two sources and place result 10 S1
-FSUBdDdS1dS2: br.n return ;return from subroutine
- fsub.ddd r5,r5,r7 ;add the two sources and place result 10 S1
-
-FCMP: bb0 1,r12,FCMPS2dnm ;S1 is not denorm, so S2 must be
- or r5,r0,r0 ;set S1 to zero
- or r6,r0,r0
-FCMPS2chk: bb0 0,r12,FCMPcalc ;S2 is not a denorm
-FCMPS2dnm: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-FCMPcalc: bb1 9,r9,FCMPdS1 ;branch for double precision S1
-FCMPsS1: bb1 7,r9,FCMPsS1dS2 ;branch for double precision S2
-FCMPsS1sS2: br.n return ;return from subroutine
- fcmp.sss r6,r6,r8 ;add the two sources and place result 10 S1
-FCMPsS1dS2: br.n return ;return from subroutine
- fcmp.ssd r6,r6,r7 ;add the two sources and place result 10 S1
-FCMPdS1: bb1 7,r9,FCMPdS1dS2 ;branch for double precision S2
-FCMPdS1sS2: br.n return ;return from subroutine
- fcmp.sds r6,r5,r8 ;add the two sources and place result 10 S1
-FCMPdS1dS2: br.n return ;return from subroutine
- fcmp.sdd r6,r5,r7 ;add the two sources and place result 10 S1
-
-FMUL: bb0 1,r12,FMULS2dnm ;S1 is not denorm, so S2 must be
- or r5,r0,r0 ;set S1 to zero
- or r6,r0,r0
-FMULS2chk: bb0 0,r12,FMULcalc ;S2 is not a denorm
-FMULS2dnm: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-FMULcalc: bb1 5,r9,FMULdD ;branch for double precision destination
-FMULsD: bb1 9,r9,FMULsDdS1 ;branch for double precision S1
-FMULsDsS1: bb1 7,r9,FMULsDsS1dS2 ;branch for double precision S2
-FMULsDsS1sS2: br.n return ;return from subroutine
- fmul.sss r6,r6,r8 ;add the two sources and place result 10 S1
-FMULsDsS1dS2: br.n return ;return from subroutine
- fmul.ssd r6,r6,r7 ;add the two sources and place result 10 S1
-FMULsDdS1: bb1 7,r9,FMULsDdS1dS2 ;branch for double precision S2
-FMULsDdS1sS2: br.n return ;return from subroutine
- fmul.sds r6,r5,r8 ;add the two sources and place result 10 S1
-FMULsDdS1dS2: br.n return ;return from subroutine
- fmul.sdd r6,r5,r7 ;add the two sources and place result 10 S1
-FMULdD: bb1 9,r9,FMULdDdS1 ;branch for double precision S1
-FMULdDsS1: bb1 7,r9,FMULdDsS1dS2 ;branch for double precision S2
-FMULdDsS1sS2: br.n return ;return from subroutine
- fmul.dss r5,r6,r8 ;add the two sources and place result 10 S1
-FMULdDsS1dS2: br.n return ;return from subroutine
- fmul.dsd r5,r6,r7 ;add the two sources and place result 10 S1
-FMULdDdS1: bb1 7,r9,FMULdDdS1dS2 ;branch for double precision S2
-FMULdDdS1sS2: br.n return ;return from subroutine
- fmul.dds r5,r5,r8 ;add the two sources and place result 10 S1
-FMULdDdS1dS2: br.n return ;return from subroutine
- fmul.ddd r5,r5,r7 ;add the two sources and place result 10 S1
-
-FDIV: bb0 1,r12,FDIVS2dnm ;S1 is not denorm, so S2 must be
- or r5,r0,r0 ;set S1 to zero
- or r6,r0,r0
-FDIVS2chk: bb0 0,r12,FDIVcalc ;S2 is not a denorm
-FDIVS2dnm: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-FDIVcalc: bb1 5,r9,FDIVdD ;branch for double precision destination
-FDIVsD: bb1 9,r9,FDIVsDdS1 ;branch for double precision S1
-FDIVsDsS1: bb1 7,r9,FDIVsDsS1dS2 ;branch for double precision S2
-FDIVsDsS1sS2: fdiv.sss r6,r6,r8 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVsDsS1dS2: fdiv.ssd r6,r6,r7 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVsDdS1: bb1 7,r9,FDIVsDdS1dS2 ;branch for double precision S2
-FDIVsDdS1sS2: fdiv.sds r6,r5,r8 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVsDdS1dS2: fdiv.sdd r6,r5,r7 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVdD: bb1 9,r9,FDIVdDdS1 ;branch for double precision S1
-FDIVdDsS1: bb1 7,r9,FDIVdDsS1dS2 ;branch for double precision S2
-FDIVdDsS1sS2: fdiv.dss r5,r6,r8 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVdDsS1dS2: fdiv.dsd r5,r6,r7 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVdDdS1: bb1 7,r9,FDIVdDdS1dS2 ;branch for double precision S2
-FDIVdDdS1sS2: fdiv.dds r5,r5,r8 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-FDIVdDdS1dS2: fdiv.ddd r5,r5,r7 ;add the two sources and place result 10 S1
- br return ;return from subroutine
-
-;FSQRT: or r7,r0,r0 ;set S2 to zero
-; or r8,r0,r0
-;FSQRTcalc: bb1 5,r9,FSQRTdD ;branch for double precision destination
-;FSQRTsD: bb1 7,r9,FSQRTsDdS2 ;branch for double precision S2
-;FSQRTsDsS2: br.n return ;return from subroutine
- ;fsqrt.ss r6,r8 ;add the two sources and place result 10 S1
-;FSQRTsDdS2: br.n return ;return from subroutine
- ;fsqrt.sd r6,r7 ;add the two sources and place result 10 S1
-;FSQRTdD: bb1 7,r9,FSQRTdDdS2 ;branch for double precision S2
-;FSQRTdDsS2: br.n return ;return from subroutine
- ;fsqrt.ds r5,r8 ;add the two sources and place result 10 S1
-;FSQRTdDdS2: br.n return ;return from subroutine
- ;fsqrt.dd r5,r7 ;add the two sources and place result 10 S1
-
-INT: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-INTcalc: bb1 7,r9,INTdS2 ;branch for double precision S2
-INTsS2: br.n return ;return from subroutine
- int.ss r6,r8 ;add the two sources and place result 10 S1
-INTdS2: br.n return ;return from subroutine
- int.sd r6,r7 ;add the two sources and place result 10 S1
-
-NINT: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-NINTcalc: bb1 7,r9,NINTdS2 ;branch for double precision S2
-NINTsS2: br.n return ;return from subroutine
- nint.ss r6,r8 ;add the two sources and place result 10 S1
-NINTdS2: br.n return ;return from subroutine
- nint.sd r6,r7 ;add the two sources and place result 10 S1
-
-TRNC: or r7,r0,r0 ;set S2 to zero
- or r8,r0,r0
-TRNCcalc: bb1 7,r9,TRNCdS2 ;branch for double precision S2
-TRNCsS2: br.n return ;return from subroutine
- trnc.ss r6,r8 ;add the two sources and place result 10 S1
-TRNCdS2: trnc.sd r6,r7 ;add the two sources and place result 10 S1
-
-
-;Return to the routine that detected the reserved operand.
-
-return: ld r1,r31,0 ;load return address
- jmp r1 ;return from subroutine
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
-#ifndef __LUNA_SUB_H__
-#include "luna_sub.h"
-#endif
- global _zero
- text
-
-;S1 and/or S2 is an infinity, and the other operand may be a zero.
-;Knowing which operands are infinity, check the remaining operands for zeros.
-
-_zero: bb0 s1inf,r12,S1noinf ;see if S1 is zero
- bb0 s2inf,r12,S2noinf ;see if S2 is zero
- jmp r1 ;return from function
-
-;See if S1 is zero. Whether or not S1 is a zero, being in this routine
-;implies that S2 is infinity, so return to subroutine infinity after
-;completing this code. Set the s1zero flag in r12 if S1 is zero.
-
-S1noinf: bb1 s1size,r9,S1noinfd ;work with double precision operand
-S1noinfs: or r10,r0,r5 ;load high word into r10
- clr r10,r10,1<sign> ;clear the sign bit
- extu r11,r6,3<29> ;extract lower 3 bits of mantissa
- or r10,r10,r11 ;or these 3 bits with high word
- bcnd ne0,r10,operation ;do not set zero flag
- jmp.n r1 ;since this operand was not infinity,
- ;S2 must have been, so return from
- ;function
- set r12,r12,1<s1zero> ;set zeroflag
-S1noinfd: clr r10,r5,1<sign> ;clear the sign bit
- or r10,r6,r10 ;or high and low word
- bcnd ne0,r10,operation ;do not set zero flag
- jmp.n r1 ;since this operand was not infinity,
- ;S2 must have been, so return from
- ;function
- set r12,r12,1<s1zero> ;set zeroflag
-
-
-;Check S2 for zero. If it is zero, then set the s2zero flag in r12.
-
-S2noinf: bb1 s2size,r9,S2noinfd ;work with double precision operand
-S2noinfs: or r10,r0,r7 ;load high word into r10
- clr r10,r10,1<sign> ;clear the sign bit
- extu r11,r8,3<29> ;extract lower 3 bits of mantissa
- or r10,r10,r11 ;or these 3 bits with high word
- bcnd ne0,r10,operation ;do not set zero flag
- jmp.n r1 ;since this operand was not infinity,
- ;S1 must have been, so return from
- ;function
- set r12,r12,1<s2zero> ;set zeroflag
-S2noinfd: clr r10,r7,1<sign> ;clear the sign bit
- or r10,r8,r10 ;or high and low word
- bcnd ne0,r10,operation ;do not set zero flag
- set r12,r12,1<s2zero> ;set zeroflag
- ;since this operand was not infinity,
- ;S1 must have been, so return from
- ;function
-operation: jmp r1 ;return from function
-
- data
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-
- text
- align 4
-; input: r3 is the excepton frame
-_Xfp_imprecise: global _Xfp_imprecise
- or r29, r3, r0 ; r29 is now the E.F.
- subu r31, r31, 40
- st r1, r31, 32
- st r29, r31, 36
-
- ld r2 , r29, EF_FPSR * 4
- ld r3 , r29, EF_FPCR * 4
- ld r4 , r29, EF_FPECR * 4
- ld r10, r29, EF_FPRH * 4
- ld r11, r29, EF_FPRL * 4
- ld r12, r29, EF_FPIT * 4
-
-;Load into r1 the return address for the exception handlers. Looking
-;at FPECR, branch to the appropriate exception handler.
-
- or.u r1,r0,hi16(fpui_wrapup);load return address of functions
- or r1,r1,lo16(fpui_wrapup)
-
- bb0 2,r4,2f ;branch to FPunderflow if bit set
- br _FPunderflow
- 2: bb0 1,r4,3f ;branch to FPoverflow if bit set
- br _FPoverflow
- 3:
-#ifdef HANDLER
- br _handler ;branch to handler since bit will be set
- ;for inexact
-#endif
- /* should never get here!!!! */
- data
- align 4
- 1: string "error in inprecise fp exception handler, r4 is 0x%08x\n\0"
- align 4
- text
- or.u r2, r0, hi16(1b)
- or r2, r2, lo16(1b)
- or r3, r4, r0
- bsr _printf
- or.u r2, r0, hi16(1b)
- or r2, r2, lo16(1b)
- bsr _panic
-
-fpui_wrapup:
- tb1 0,r0,0 ;make sure all floating point operations
- ldcr r5, psr ;load the PSR
- ;have finished
- or r5, r5, 0x2 ;disable interrupts
- stcr r5, psr
-#if 0
-Why is this done? -- it screws up things later.
- or r5, r5, 0x8 ;set SFU 1 disable bit, disable SFU 1
- stcr r5, psr
-#endif
- ld r1, r31, 32
- ld r29,r31, 36
- addu r31, r31, 40
-
- ; write back the results
- extu r2, r12, 5<0>
- addu r3, r29, EF_R0*4
- bb0 destsize, r12, Iwritesingle
- st r10, r3 [r2]
- addu r2, r2, 1
- clr r2, r2, 27<5>
-Iwritesingle:
- st r11, r3 [r2]
-;Return..
- jmp r1
diff --git a/sys/arch/mvme88k/m88k/machdep.c b/sys/arch/mvme88k/m88k/machdep.c
deleted file mode 100644
index 28eb27967ff..00000000000
--- a/sys/arch/mvme88k/m88k/machdep.c
+++ /dev/null
@@ -1,1360 +0,0 @@
-/*
- * 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
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/signalvar.h>
-#include <sys/kernel.h>
-#include <sys/map.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/reboot.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/clist.h>
-#include <sys/callout.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/msgbuf.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/mount.h>
-#include <sys/user.h>
-#include <sys/exec.h>
-#include <sys/vnode.h>
-#include <sys/sysctl.h>
-#include <sys/errno.h>
-#ifdef SYSVMSG
-#include <sys/msg.h>
-#endif
-#ifdef SYSVSEM
-#include <sys/sem.h>
-#endif
-#ifdef SYSVSHM
-#include <sys/shm.h>
-#endif
-
-#include <machine/cpu.h>
-#include <machine/reg.h>
-#include <machine/psl.h>
-#include <machine/locore.h>
-#include <machine/board.h>
-#include <machine/trap.h>
-#include <machine/bug.h>
-
-#include <dev/cons.h>
-
-#include <vm/vm.h>
-#include <vm/vm_map.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#define __IS_MACHDEP_C__
-#include <assym.s> /* EF_EPSR, etc. */
-#include <machine/m88100.h> /* DMT_VALID */
-#include <machine/m882xx.h> /* CMMU stuff */
-#if DDB
-# include <machine/db_machdep.h>
-#endif /* DDB */
-
-#if 0
-#include <machine/m88100.h> /* DMT_VALID */
-#include <machine/m882xx.h> /* CMMU stuff */
-#include <vm/vm.h>
-#include <vm/vm_kern.h> /* kernel_map */
-#include <sys/param.h>
-#include <sys/msgbuf.h>
-#include <sys/buf.h>
-#include <machine/locore.h> /* USERMODE */
-/*
-#include <machine/nvram.h>
-*/
-#include <sys/types.h>
-#endif /* 0 */
-
-static int waittime = -1;
-
-static void level0_intr(int, unsigned *);
-static void level1_intr(int, unsigned *);
-static void level2_intr(int, unsigned *);
-static void level3_intr(int, unsigned *);
-static void level4_intr(int, unsigned *);
-static void level5_intr(int, unsigned *);
-static void level6_intr(int, unsigned *);
-static void level7_intr(int, unsigned *);
-
-unsigned char *ivec[] = {
- (unsigned char *)0xFFFE007,
- (unsigned char *)0xFFFE00B,
- (unsigned char *)0xFFFE00F,
- (unsigned char *)0xFFFE013,
- (unsigned char *)0xFFFE017,
- (unsigned char *)0xFFFE01B,
- (unsigned char *)0xFFFE01F,
-};
-
-static void (*int_handler[8])() =
-{
- level0_intr,
- level1_intr,
- level2_intr,
- level3_intr,
- level4_intr,
- level5_intr,
- level6_intr,
- level7_intr,
-};
-
-unsigned char *int_mask_level = (unsigned char *)INT_MASK_LEVEL;
-unsigned char *int_pri_level = (unsigned char *)INT_PRI_LEVEL;
-unsigned char *iackaddr;
-
-int physmem; /* available physical memory, in pages */
-int cold;
-vm_offset_t avail_end, avail_start, avail_next;
-int msgbufmapped = 0;
-int foodebug = 0;
-int longformat = 0;
-
-extern char kstack[]; /* kernel stack - actually this is == UADDR */
-extern char *cpu_string;
-extern short exframesize[];
-
-/*
- * Declare these as initialized data so we can patch them.
- */
-int nswbuf = 0;
-#ifdef NBUF
-int nbuf = NBUF;
-#else
-int nbuf = 0;
-#endif
-#ifdef BUFPAGES
-int bufpages = BUFPAGES;
-#else
-int bufpages = 0;
-#endif
-int *nofault;
-
-caddr_t allocsys __P((caddr_t));
-
-/*
- * Info for CTL_HW
- */
-char machine[] = "MVME187"; /* cpu "architecture" */
-char cpu_model[120];
-extern char version[];
-
- /*
- * Console initialization: called early on from main,
- * before vm init or startup. Do enough configuration
- * to choose and initialize a console.
- */
-void
-consinit()
-{
-
- /*
- * Initialize the console before we print anything out.
- */
- cninit();
-
-#if defined (DDB)
- kdb_init();
- if (boothowto & RB_KDB)
- Debugger();
-#endif
-}
-
-/*
- * Figure out how much real memory is available.
- * Start looking from the megabyte after the end of the kernel data,
- * until we find non-memory.
- */
-vm_offset_t
-size_memory(void)
-{
- volatile unsigned int *look;
- unsigned int *max;
- extern char end[];
- #define PATTERN 0x5a5a5a5a
- #define STRIDE (4*1024) /* 4k at a time */
- #define Roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1))
-
- /*
- * count it up.
- */
- max = (void*)MAXPHYSMEM;
- for (look = (void*)Roundup(end, STRIDE); look < max;
- look = (int*)((unsigned)look + STRIDE)) {
- unsigned save;
-
- /* if can't access, we've reached the end */
- if (foodebug)
- printf("%x\n", look);
- if (badwordaddr((vm_offset_t)look)) {
- printf("%x\n", look);
- look = (int *)((int)look - STRIDE);
- break;
- }
-
-#if 1
- /*
- * If we write a value, we expect to read the same value back.
- * We'll do this twice, the 2nd time with the opposite bit
- * pattern from the first, to make sure we check all bits.
- */
- save = *look;
- if (*look = PATTERN, *look != PATTERN)
- break;
- if (*look = ~PATTERN, *look != ~PATTERN)
- break;
- *look = save;
-#endif
- }
-
- physmem = btoc(trunc_page((unsigned)look)); /* in pages */
- return(trunc_page((unsigned)look));
-}
-
-void
-identifycpu()
-{
- /* XXX -take this one out. It can be done in m187_bootstrap() */
- strcpy(cpu_model, "Motorola M88K");
- printf("Model: %s\n", cpu_model);
-}
-
-/* The following two functions assume UPAGES == 3 */
-#if UPAGES != 3
-#error "UPAGES changed?"
-#endif
-
-void
-save_u_area(struct proc *p, vm_offset_t va)
-{
- p->p_md.md_upte[0] = kvtopte(va)->bits;
- p->p_md.md_upte[1] = kvtopte(va + NBPG)->bits;
- p->p_md.md_upte[2] = kvtopte(va + NBPG + NBPG)->bits;
-}
-
-void
-load_u_area(struct proc *p)
-{
- pte_template_t *t;
-
- t = kvtopte(UADDR);
- t->bits = p->p_md.md_upte[0];
- t = kvtopte(UADDR + NBPG);
- t->bits = p->p_md.md_upte[1];
- t = kvtopte(UADDR + NBPG + NBPG);
- t->bits = p->p_md.md_upte[2];
- cmmu_flush_tlb(1, UADDR, 3 * NBPG);
-}
-
-
-void
-cpu_startup()
-{
- caddr_t v;
- int sz, i;
- vm_size_t size;
- int base, residual;
- vm_offset_t minaddr, maxaddr, uarea_pages;
- extern vm_offset_t miniroot;
-
- /*
- * Initialize error message buffer (at end of core).
- * avail_end was pre-decremented in m1x7_init.
- */
- for (i = 0; i < btoc(sizeof(struct msgbuf)); i++)
- pmap_enter(kernel_pmap, (vm_offset_t)msgbufp,
- avail_end + i * NBPG, VM_PROT_ALL, TRUE);
- msgbufmapped = 1;
-
- printf(version);
- identifycpu();
- printf("real mem = %d\n", ctob(physmem));
-
- /*
- * Find out how much space we need, allocate it,
- * and then give everything true virtual addresses.
- */
- sz = (int)allocsys((caddr_t)0);
- if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0)
- panic("startup: no room for tables");
- if (allocsys(v) - v != sz)
- panic("startup: table size inconsistency");
-
- /*
- * Grab UADDR virtual address
- */
-
- uarea_pages = UADDR;
-
- vm_map_find(kernel_map, vm_object_allocate(PAGE_SIZE * UPAGES), 0,
- (vm_offset_t *)&uarea_pages, PAGE_SIZE * UPAGES, TRUE);
-
- if (uarea_pages != UADDR) {
- printf("uarea_pages %x: UADDR not free\n", uarea_pages);
- panic("bad UADDR");
- }
- /*
- * Now allocate buffers proper. They are different than the above
- * in that they usually occupy more virtual memory than physical.
- */
- size = MAXBSIZE * nbuf;
- buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
- &maxaddr, size, TRUE);
- minaddr = (vm_offset_t)buffers;
- if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
- (vm_offset_t *)&minaddr, size, FALSE) != KERN_SUCCESS)
- panic("startup: cannot allocate buffers");
- if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
- /* don't want to alloc more physical mem than needed */
- bufpages = btoc(MAXBSIZE) * nbuf;
- }
- base = bufpages / nbuf;
- residual = bufpages % nbuf;
- for (i = 0; i < nbuf; i++) {
- vm_size_t curbufsize;
- vm_offset_t curbuf;
-
- /*
- * First <residual> buffers get (base+1) physical pages
- * allocated for them. The rest get (base) physical pages.
- *
- * The rest of each buffer occupies virtual space,
- * but has no physical memory allocated for it.
- */
- curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
- curbufsize = CLBYTES * (i < residual ? base+1 : base);
- vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
- vm_map_simplify(buffer_map, curbuf);
- }
-
- /*
- * Allocate a submap for exec arguments. This map effectively
- * limits the number of processes exec'ing at any time.
- */
- exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
- 16*NCARGS, TRUE);
-
- /*
- * Allocate a map for IO.
- */
- phys_map = vm_map_create(kernel_pmap, IO_SPACE_START,
- IO_SPACE_END, TRUE);
- if (phys_map == NULL)
- panic("cpu_startup: unable to create physmap");
-
- /*
- * Finally, allocate mbuf pool. Since mclrefcnt is an off-size
- * we use the more space efficient malloc in place of kmem_alloc.
- */
- mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
- M_MBUF, M_NOWAIT);
- bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
- mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
- VM_MBUF_SIZE, FALSE);
-
- /*
- * Initialize callouts
- */
- callfree = callout;
- for (i = 1; i < ncallout; i++)
- callout[i-1].c_next = &callout[i];
- callout[i-1].c_next = NULL;
-
- printf("avail mem = %d\n", ptoa(cnt.v_free_count));
- printf("using %d buffers containing %d bytes of memory\n",
- nbuf, bufpages * CLBYTES);
-
- mfs_initminiroot(miniroot);
- /*
- * Set up buffers, so they can be used to read disk labels.
- */
- bufinit();
-
- /*
- * Configure the system.
- */
- nofault = NULL;
- configure();
-
- dumpconf();
-}
-
-/*
- * Allocate space for system data structures. We are given
- * a starting virtual address and we return a final virtual
- * address; along the way we set each data structure pointer.
- *
- * We call allocsys() with 0 to find out how much space we want,
- * allocate that much and fill it with zeroes, and then call
- * allocsys() again with the correct base virtual address.
- */
-caddr_t
-allocsys(v)
- register caddr_t v;
-{
-
-#define valloc(name, type, num) \
- v = (caddr_t)(((name) = (type *)v) + (num))
-
-#ifdef REAL_CLISTS
- valloc(cfree, struct cblock, nclist);
-#endif
- valloc(callout, struct callout, ncallout);
- valloc(swapmap, struct map, nswapmap = maxproc * 2);
-#ifdef SYSVSHM
- valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
-#endif
-#ifdef SYSVSEM
- valloc(sema, struct semid_ds, seminfo.semmni);
- valloc(sem, struct sem, seminfo.semmns);
- /* This is pretty disgusting! */
- valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
-#endif
-#ifdef SYSVMSG
- valloc(msgpool, char, msginfo.msgmax);
- valloc(msgmaps, struct msgmap, msginfo.msgseg);
- valloc(msghdrs, struct msg, msginfo.msgtql);
- valloc(msqids, struct msqid_ds, msginfo.msgmni);
-#endif
-
- /*
- * Determine how many buffers to allocate (enough to
- * hold 5% of total physical memory, but at least 16).
- * Allocate 1/2 as many swap buffer headers as file i/o buffers.
- */
- if (bufpages == 0)
- if (physmem < btoc(2 * 1024 * 1024))
- bufpages = (physmem / 10) / CLSIZE;
- else
- bufpages = (physmem / 20) / CLSIZE;
- if (nbuf == 0) {
- nbuf = bufpages;
- if (nbuf < 16)
- nbuf = 16;
- }
- if (nswbuf == 0) {
- nswbuf = (nbuf / 2) &~ 1; /* force even */
- if (nswbuf > 256)
- nswbuf = 256; /* sanity */
- }
- valloc(swbuf, struct buf, nswbuf);
- valloc(buf, struct buf, nbuf);
- return v;
-}
-
-/*
- * Set registers on exec.
- * Clear all except sp and pc.
- */
-/* ARGSUSED */
-void
-setregs(p, pack, stack, retval)
- struct proc *p;
- struct exec_package *pack;
- u_long stack;
- int retval[2];
-{
- register struct trapframe *tf = p->p_md.md_tf;
- register int psr;
-
- /*
- * The syscall will ``return'' to snip; set it.
- * Set the rest of the registers to 0 except for r31 (stack pointer,
- * built in exec()) and psr (supervisor bit).
- */
- psr = tf->epsr & PSR_SUPERVISOR_MODE_BIT;
-#if 0
- /*
- I don't think I need to mess with fpstate on 88k because
- we make sure the floating point pipeline is drained in
- locore.s. Should check on this later. Nivas.
- */
-
- if ((fs = p->p_md.md_fpstate) != NULL) {
- /*
- * We hold an FPU state. If we own *the* FPU chip state
- * we must get rid of it, and the only way to do that is
- * to save it. In any case, get rid of our FPU state.
- */
- if (p == fpproc) {
- savefpstate(fs);
- fpproc = NULL;
- }
- free((void *)fs, M_SUBPROC);
- p->p_md.md_fpstate = NULL;
- }
-#endif /* 0 */
- bzero((caddr_t)tf, sizeof *tf);
- tf->epsr = psr;
- tf->snip = pack->ep_entry & ~3;
- tf->sfip = tf->snip + 4;
- tf->r[31] = stack;
- retval[1] = 0;
-}
-
-/*
- * WARNING: code in locore.s assumes the layout shown for sf_signum
- * thru sf_handler so... don't screw with them!
- */
-struct sigframe {
- int sf_signo; /* signo for handler */
- int sf_code; /* additional info for handler */
- struct sigcontext *sf_scp; /* context ptr for handler */
- sig_t sf_handler; /* handler addr for u_sigc */
- struct sigcontext sf_sc; /* actual context */
-};
-
-#ifdef DEBUG
-int sigdebug = 0;
-int sigpid = 0;
-#define SDB_FOLLOW 0x01
-#define SDB_KSTACK 0x02
-#define SDB_FPSTATE 0x04
-#endif
-
-/*
- * Send an interrupt to process.
- */
-void
-sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig, mask;
- unsigned long code;
-{
- register struct proc *p = curproc;
- register struct trapframe *tf;
- register struct sigacts *psp = p->p_sigacts;
- struct sigframe *fp;
- int oonstack, fsize;
- struct sigframe sf;
- int addr;
- extern char sigcode[], esigcode[];
-
-#define szsigcode (esigcode - sigcode)
-
- tf = p->p_md.md_tf;
- oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
- /*
- * Allocate and validate space for the signal handler
- * context. Note that if the stack is in data space, the
- * call to grow() is a nop, and the copyout()
- * will fail if the process has not already allocated
- * the space with a `brk'.
- */
- fsize = sizeof(struct sigframe);
- if ((psp->ps_flags & SAS_ALTSTACK) &&
- (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
- (psp->ps_sigonstack & sigmask(sig))) {
- fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
- psp->ps_sigstk.ss_size - fsize);
- psp->ps_sigstk.ss_flags |= SA_ONSTACK;
- } else
- fp = (struct sigframe *)(tf->r[31] - fsize);
- if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
- (void)grow(p, (unsigned)fp);
-#ifdef DEBUG
- if ((sigdebug & SDB_FOLLOW) ||
- (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
- p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
-#endif
- /*
- * Build the signal context to be used by sigreturn.
- */
- sf.sf_signo = sig;
- sf.sf_code = code;
- sf.sf_scp = &fp->sf_sc;
- sf.sf_sc.sc_onstack = oonstack;
- sf.sf_sc.sc_mask = mask;
- /*
- * Copy the whole user context into signal context that we
- * are building.
- */
-
- bcopy((caddr_t)tf->r, (caddr_t)sf.sf_sc.sc_regs,
- sizeof(sf.sf_sc.sc_regs));
- sf.sf_sc.sc_xip = tf->sxip;
- sf.sf_sc.sc_nip = tf->snip;
- sf.sf_sc.sc_fip = tf->sfip;
- sf.sf_sc.sc_ps = tf->epsr;
- sf.sf_sc.sc_sp = tf->r[31];
- sf.sf_sc.sc_fpsr = tf->fpsr;
- sf.sf_sc.sc_fpcr = tf->fpcr;
- sf.sf_sc.sc_ssbr = tf->ssbr;
- sf.sf_sc.sc_dmt0 = tf->dmt0;
- sf.sf_sc.sc_dmd0 = tf->dmd0;
- sf.sf_sc.sc_dma0 = tf->dma0;
- sf.sf_sc.sc_dmt1 = tf->dmt1;
- sf.sf_sc.sc_dmd1 = tf->dmd1;
- sf.sf_sc.sc_dma1 = tf->dma1;
- sf.sf_sc.sc_dmt2 = tf->dmt2;
- sf.sf_sc.sc_dmd2 = tf->dmd2;
- sf.sf_sc.sc_dma2 = tf->dma2;
- sf.sf_sc.sc_fpecr = tf->fpecr;
- sf.sf_sc.sc_fphs1 = tf->fphs1;
- sf.sf_sc.sc_fpls1 = tf->fpls1;
- sf.sf_sc.sc_fphs2 = tf->fphs2;
- sf.sf_sc.sc_fpls2 = tf->fpls2;
- sf.sf_sc.sc_fppt = tf->fppt;
- sf.sf_sc.sc_fprh = tf->fprh;
- sf.sf_sc.sc_fprl = tf->fprl;
- sf.sf_sc.sc_fpit = tf->fpit;
- if (copyout((caddr_t)&sf, (caddr_t)&fp, sizeof sf)) {
- /*
- * Process has trashed its stack; give it an illegal
- * instruction to halt it in its tracks.
- */
- SIGACTION(p, SIGILL) = SIG_DFL;
- sig = sigmask(SIGILL);
- p->p_sigignore &= ~sig;
- p->p_sigcatch &= ~sig;
- p->p_sigmask &= ~sig;
- psignal(p, SIGILL);
- return;
- }
- /*
- * Build the argument list for the signal handler.
- * Signal trampoline code is at base of user stack.
- */
- addr = (int)PS_STRINGS - szsigcode;
- tf->snip = addr & ~3;
- tf->sfip = tf->snip + 4;
- tf->r[31] = (unsigned)fp;
-#ifdef DEBUG
- if ((sigdebug & SDB_FOLLOW) ||
- (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig(%d): sig %d returns\n",
- p->p_pid, sig);
-#endif
-}
-
-/*
- * System call to cleanup state after a signal
- * has been taken. Reset signal mask and
- * stack state from context left by sendsig (above).
- * Return to previous pc and psl as specified by
- * context left by sendsig. Check carefully to
- * make sure that the user has not modified the
- * psl to gain improper priviledges or to cause
- * a machine fault.
- */
-struct sigreturn_args {
- struct sigcontext *scp;
-};
-/* ARGSUSED */
-sigreturn(p, uap, retval)
- struct proc *p;
- struct sigreturn_args *uap;
- int *retval;
-{
- register struct sigcontext *scp;
- register struct trapframe *tf;
- struct sigcontext ksc;
- int error;
-
- scp = uap->scp;
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW)
- printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
-#endif
- if ((int)scp & 3 || useracc((caddr_t)scp, sizeof *scp, B_WRITE) == 0)
- return (EINVAL);
- tf = p->p_md.md_tf;
- /*
- * xip, nip and fip must be multiples of 4. This is all
- * that is required; if it holds, just do it.
- */
- if (((scp->sc_xip | scp->sc_nip | scp->sc_fip) & 3) != 0)
- return (EINVAL);
- bcopy((caddr_t)scp->sc_regs, (caddr_t)tf->r,
- sizeof(scp->sc_regs));
- tf->sxip = scp->sc_xip;
- tf->snip = scp->sc_nip;
- tf->sfip = scp->sc_fip;
- tf->epsr = scp->sc_ps;
- tf->r[31] = scp->sc_sp;
- tf->fpsr = scp->sc_fpsr;
- tf->fpcr = scp->sc_fpcr;
- tf->ssbr = scp->sc_ssbr;
- tf->dmt0 = scp->sc_dmt0;
- tf->dmd0 = scp->sc_dmd0;
- tf->dma0 = scp->sc_dma0;
- tf->dmt1 = scp->sc_dmt1;
- tf->dmd1 = scp->sc_dmd1;
- tf->dma1 = scp->sc_dma1;
- tf->dmt2 = scp->sc_dmt2;
- tf->dmd2 = scp->sc_dmd2;
- tf->dma2 = scp->sc_dma2;
- tf->fpecr = scp->sc_fpecr;
- tf->fphs1 = scp->sc_fphs1;
- tf->fpls1 = scp->sc_fpls1;
- tf->fphs2 = scp->sc_fphs2;
- tf->fpls2 = scp->sc_fpls2;
- tf->fppt = scp->sc_fppt;
- tf->fprh = scp->sc_fprh;
- tf->fprl = scp->sc_fprl;
- tf->fpit = scp->sc_fpit;
-
- tf->epsr = scp->sc_ps;
-
- /*
- * Restore the user supplied information
- */
- if (scp->sc_onstack & 01)
- p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
- else
- p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
- p->p_sigmask = scp->sc_mask &~ sigcantmask;
- return (EJUSTRETURN);
-}
-
-void
-bootsync(void)
-{
- if (waittime < 0) {
- register struct buf *bp;
- int iter, nbusy;
-
- waittime = 0;
- (void) spl0();
- printf("syncing disks... ");
- /*
- * Release vnodes held by texts before sync.
- */
- if (panicstr == 0)
- vnode_pager_umount(NULL);
- sync(&proc0, (void *)NULL, (int *)NULL);
-
- for (iter = 0; iter < 20; iter++) {
- nbusy = 0;
- for (bp = &buf[nbuf]; --bp >= buf; )
- if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
- nbusy++;
- if (nbusy == 0)
- break;
- printf("%d ", nbusy);
- delay(40000 * iter);
- }
- if (nbusy)
- printf("giving up\n");
- else
- printf("done\n");
- /*
- * If we've been adjusting the clock, the todr
- * will be out of synch; adjust it now.
- */
- resettodr();
- }
-}
-
-doboot()
-{
- bugreturn();
-}
-
-void
-boot(howto)
- register int howto;
-{
- /* take a snap shot before clobbering any registers */
- if (curproc)
- savectx(curproc->p_addr, 0);
-
- boothowto = howto;
- if ((howto&RB_NOSYNC) == 0)
- bootsync();
- splhigh(); /* extreme priority */
- if (howto&RB_HALT) {
- printf("halted\n\n");
- bugreturn();
- } else {
- if (howto & RB_DUMP)
- dumpsys();
- doboot();
- /*NOTREACHED*/
- }
- /*NOTREACHED*/
-}
-
-unsigned dumpmag = 0x8fca0101; /* magic number for savecore */
-int dumpsize = 0; /* also for savecore */
-long dumplo = 0;
-
-dumpconf()
-{
- int nblks;
-
- dumpsize = physmem;
- if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
- nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
- if (dumpsize > btoc(dbtob(nblks - dumplo)))
- dumpsize = btoc(dbtob(nblks - dumplo));
- else if (dumplo == 0)
- dumplo = nblks - btodb(ctob(physmem));
- }
- /*
- * Don't dump on the first CLBYTES (why CLBYTES?)
- * in case the dump device includes a disk label.
- */
- if (dumplo < btodb(CLBYTES))
- dumplo = btodb(CLBYTES);
-}
-
-/*
- * Doadump comes here after turning off memory management and
- * getting on the dump stack, either when called above, or by
- * the auto-restart code.
- */
-dumpsys()
-{
-
- msgbufmapped = 0;
- if (dumpdev == NODEV)
- return;
- /*
- * For dumps during autoconfiguration,
- * if dump device has already configured...
- */
- if (dumpsize == 0)
- dumpconf();
- if (dumplo < 0)
- return;
- printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
- printf("dump ");
- switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
-
- case ENXIO:
- printf("device bad\n");
- break;
-
- case EFAULT:
- printf("device not ready\n");
- break;
-
- case EINVAL:
- printf("area improper\n");
- break;
-
- case EIO:
- printf("i/o error\n");
- break;
-
- default:
- printf("succeeded\n");
- break;
- }
-}
-
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points. We do this by returning the current time
- * plus the amount of time since the last clock interrupt (clock.c:clkread).
- *
- * Check that this time is no less than any previously-reported time,
- * which could happen around the time of a clock adjustment. Just for fun,
- * we guarantee that the time will be greater than the value obtained by a
- * previous call.
- */
-void
-microtime(tvp)
- register struct timeval *tvp;
-{
- int s = splhigh();
- static struct timeval lasttime;
-
- *tvp = time;
- tvp->tv_usec += clkread();
- while (tvp->tv_usec > 1000000) {
- tvp->tv_sec++;
- tvp->tv_usec -= 1000000;
- }
- if (tvp->tv_sec == lasttime.tv_sec &&
- tvp->tv_usec <= lasttime.tv_usec &&
- (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
- tvp->tv_sec++;
- tvp->tv_usec -= 1000000;
- }
- lasttime = *tvp;
- splx(s);
-}
-
-#ifdef PGINPROF
-/*
- * Return the difference (in microseconds)
- * between the current time and a previous
- * time as represented by the arguments.
- * If there is a pending clock interrupt
- * which has not been serviced due to high
- * ipl, return error code.
- */
-unsigned vmtime(int otime, int olbolt, int oicr)
-{
- return ((time.tv_sec-otime)*60 + lbolt-olbolt)*16667;
-}
-#endif /* PGINPROF */
-
-badwordaddr(void *addr)
-{
- return badaddr((vm_offset_t)addr, 4);
-}
-
-/* returns positive if memory is not there; */
-unsigned check_memory(void *addr, unsigned flag)
-{
- return badaddr((vm_offset_t)addr, 1);
-}
-
-void start_clock(void)
-{
- printf("Start clock\n");
-}
-
-static void
-level0_intr(int level, unsigned *frame)
-{
- printf("Spurious interrupt\n");
-}
-
-static void
-level1_intr(int level, unsigned *frame)
-{
- register char vec;
- iackaddr = ivec[level];
-
- /* generate IACK and get the vector */
- asm volatile ("ld.b %0,%1" : "=r" (vec) : "" (iackaddr));
-}
-#if 0
-static void
-level1_intr(int level, unsigned *frame)
-{
- register char vec;
- iackaddr = ivec[level];
-
- /* generate IACK and get the vector */
- asm volatile ("ld.b %0,%1" : "=r" (vec) : "" (iackaddr));
-}
-#endif
-
-static void
-level2_intr(int level, unsigned *frame)
-{
- iackaddr = ivec[level];
-}
-
-static void
-level3_intr(int level, unsigned *frame)
-{
- iackaddr = ivec[level];
-}
-
-static void
-level4_intr(int level, unsigned *frame)
-{
- iackaddr = ivec[level];
-}
-
-static void
-level5_intr(int level, unsigned *frame)
-{
- iackaddr = ivec[level];
-}
-
-static void
-level6_intr(int level, unsigned *frame)
-{
- register char vec;
- struct clockframe clkframe;
- iackaddr = ivec[level];
-
- /* generate IACK and get the vector */
- asm volatile("ld.b %0,%1" : "=r" (vec) : "" (iackaddr));
- switch (vec){
- case TIMER1IRQ:
- break;
- case TIMER2IRQ:
- /*
- * build clockframe and pass to the clock
- * interrupt handler
- */
- clkframe.pc = frame[EF_SXIP] & ~3;
- clkframe.sr = frame[EF_EPSR];
- clkframe.ipl = frame[EF_MASK];
- clockintr(&clkframe);
- break;
- }
-}
-
-static void
-level7_intr(int level, unsigned *frame)
-{
- iackaddr = ivec[level];
-}
-
-/*
- * Device interrupt handler
- *
- * when we enter, interrupts are disabled;
- * when we leave, they should be disabled,
- * but they need not be enabled throughout
- * the routine.
- */
-
-void
-ext_int(unsigned vec, unsigned *eframe)
-{
- register unsigned char mask, level;
- register int s; /* XXX */
-
- asm volatile ("ld.b %0,%1" : "=r" (mask) : "" (int_mask_level));
- asm volatile ("ld.b %0,%1" : "=r" (level) : "" (int_pri_level));
-
- /* get the mask and stash it away in the trap frame */
- eframe[EF_MASK] = mask;
- /* and block ints level or lower */
- spln((char)mask);
- enable_interrupt();
- (*int_handler[level])(level,eframe);
- /*
- * process any remaining data access exceptions before
- * returning to assembler
- */
- disable_interrupt();
- if (eframe[EF_DMT0] && DMT_VALID)
- {
- trap(T_DATAFLT, eframe);
- data_access_emulation(eframe);
- }
- mask = eframe[EF_MASK];
- asm volatile ("st.b %0,%1" : "=r" (mask) : "" (int_mask_level));
-}
-
-/*
- * check a word wide address.
- * write < 0 -> check for write access.
- * otherwise read.
- */
-int wprobe(void *addr, unsigned int write)
-{
- /* XXX only checking reads */
- return badaddr((vm_offset_t)addr, sizeof(int));
-}
-
-cpu_exec_aout_makecmds(p, epp)
- struct proc *p;
- struct exec_package *epp;
-{
- int error = ENOEXEC;
-
-#ifdef COMPAT_SUNOS
- extern sun_exec_aout_makecmds __P((struct proc *, struct exec_package *));
- if ((error = sun_exec_aout_makecmds(p, epp)) == 0)
- return 0;
-#endif
- return error;
-}
-
-#if NOTYET
-/*
- * nvram_read(BUF, ADDRESS, SIZE)
- * nvram_write(BUF, ADDRESS, SIZE)
- *
- * Read and write non-volatile RAM.
- * Only one byte from each word in the NVRAM area is accessable.
- * ADDRESS points to the virtual starting address, which is some address
- * after the nvram start (NVRAM_ADDR). SIZE refers to virtual size.
- */
-void nvram_read(char *buf, vm_offset_t address, unsigned size)
-{
- unsigned index = (unsigned)address - NVRAM_ADDR;
- unsigned char *source = (char*)(NVRAM_ADDR + index * 4);
-
- while (size-- > 0)
- {
- *buf++ = *source;
- source += 4; /* bump up to point to next readable byte */
- }
-}
-
-void nvram_write(char *buf, vm_offset_t address, unsigned size)
-{
- unsigned index = (unsigned)address - NVRAM_ADDR;
- unsigned char *source = (char*)(NVRAM_ADDR + index * 4);
-
- while (size-- > 0)
- {
- *source = *buf++;
- source += 4; /* bump up to point to next readable byte */
- }
-}
-#endif /* NOTYET */
-
-struct sysarch_args {
- int op;
- char *parms;
-};
-
-sysarch(p, uap, retval)
- struct proc *p;
- register struct sysarch_args *uap;
- int *retval;
-{
- int error = 0;
-
- switch(uap->op) {
- default:
- error = EINVAL;
- break;
- }
- return(error);
-}
-
-/*
- * machine dependent system variables.
- */
-cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
- int *name;
- u_int namelen;
- void *oldp;
- size_t *oldlenp;
- void *newp;
- size_t newlen;
- struct proc *p;
-{
-
- /* all sysctl names are this level are terminal */
- if (namelen != 1)
- return (ENOTDIR); /* overloaded */
-
- switch (name[0]) {
- default:
- return (EOPNOTSUPP);
- }
- /*NOTREACHED*/
-}
-
-/*
- * insert an element into a queue
- */
-#undef _insque
-_insque(element, head)
- register struct prochd *element, *head;
-{
- element->ph_link = head->ph_link;
- head->ph_link = (struct proc *)element;
- element->ph_rlink = (struct proc *)head;
- ((struct prochd *)(element->ph_link))->ph_rlink=(struct proc *)element;
-}
-
-/*
- * remove an element from a queue
- */
-#undef _remque
-_remque(element)
- register struct prochd *element;
-{
- ((struct prochd *)(element->ph_link))->ph_rlink = element->ph_rlink;
- ((struct prochd *)(element->ph_rlink))->ph_link = element->ph_link;
- element->ph_rlink = (struct proc *)0;
-}
-
-#if 0
-/*
- * Below written in C to allow access to debugging code
- */
-copyinstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
- void *toaddr, *fromaddr;
-{
- int c,tally;
-
- tally = 0;
- while (maxlength--) {
- c = fubyte(fromaddr++);
- if (c == -1) {
- if(lencopied) *lencopied = tally;
- return(EFAULT);
- }
- tally++;
- *(char *)toaddr++ = (char) c;
- if (c == 0){
- if(lencopied) *lencopied = (u_int)tally;
- return(0);
- }
- }
- if(lencopied) *lencopied = (u_int)tally;
- return(ENAMETOOLONG);
-}
-
-copyoutstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
- void *fromaddr, *toaddr;
-{
- int c;
- int tally;
-
- tally = 0;
- while (maxlength--) {
- c = subyte(toaddr++, *(char *)fromaddr);
- if (c == -1) return(EFAULT);
- tally++;
- if (*(char *)fromaddr++ == 0){
- if(lencopied) *lencopied = tally;
- return(0);
- }
- }
- if(lencopied) *lencopied = tally;
- return(ENAMETOOLONG);
-}
-
-#endif /* 0 */
-
-copystr(fromaddr, toaddr, maxlength, lencopied)
- u_int *lencopied, maxlength;
- void *fromaddr, *toaddr;
-{
- u_int tally;
-
- tally = 0;
- while (maxlength--) {
- *(u_char *)toaddr = *(u_char *)fromaddr++;
- tally++;
- if (*(u_char *)toaddr++ == 0) {
- if(lencopied) *lencopied = tally;
- return(0);
- }
- }
- if(lencopied) *lencopied = tally;
- return(ENAMETOOLONG);
-}
-
-void
-putchar(char c)
-{
- bugoutchr(c);
-}
-/* dummys for now */
-
-bugsyscall()
-{
-}
-
-mmrw()
-{
-}
-
-netintr()
-{
-}
-
-MY_info(f, p, flags, s)
-struct trapframe *f;
-caddr_t p;
-int flags;
-char *s;
-{
- regdump(f);
- printf("proc %x flags %x type %s\n", p, flags, s);
-}
-
-MY_info_done(f, flags)
-struct trapframe *f;
-int flags;
-{
- regdump(f);
-}
-
-regdump(struct trapframe *f)
-{
-#define R(i) f->r[i]
- printf("R00-05: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(0),R(1),R(2),R(3),R(4),R(5));
- printf("R06-11: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(6),R(7),R(8),R(9),R(10),R(11));
- printf("R12-17: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(12),R(13),R(14),R(15),R(16),R(17));
- printf("R18-23: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(18),R(19),R(20),R(21),R(22),R(23));
- printf("R24-29: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(24),R(25),R(26),R(27),R(28),R(29));
- printf("R30-31: 0x%08x 0x%08x\n",R(30),R(31));
- printf("sxip %x snip %x sfip %x\n", f->sxip, f->snip, f->sfip);
- if (f->vector == 0x3) { /* print dmt stuff for data access fault */
- printf("dmt0 %x dmd0 %x dma0 %x\n", f->dmt0, f->dmd0, f->dma0);
- printf("dmt1 %x dmd1 %x dma1 %x\n", f->dmt1, f->dmd1, f->dma1);
- printf("dmt2 %x dmd2 %x dma2 %x\n", f->dmt2, f->dmd2, f->dma2);
- }
- if (longformat) {
- printf("fpsr %x", f->fpsr);
- printf("fpcr %x", f->fpcr);
- printf("epsr %x", f->epsr);
- printf("ssbr %x\n", f->ssbr);
- printf("dmt0 %x", f->dmt0);
- printf("dmd0 %x", f->dmd0);
- printf("dma0 %x", f->dma0);
- printf("dmt1 %x", f->dmt1);
- printf("dmd1 %x", f->dmd1);
- printf("dma1 %x", f->dma1);
- printf("dmt2 %x", f->dmt2);
- printf("dmd2 %x", f->dmd2);
- printf("dma2 %x\n", f->dma2);
- printf("fpecr %x", f->fpecr);
- printf("fphs1 %x", f->fphs1);
- printf("fpls1 %x", f->fpls1);
- printf("fphs2 %x", f->fphs2);
- printf("fpls2 %x", f->fpls2);
- printf("fppt %x", f->fppt);
- printf("fprh %x", f->fprh);
- printf("fprl %x", f->fprl);
- printf("fpit %x\n", f->fpit);
- printf("vector %x", f->vector);
- printf("mask %x", f->mask);
- printf("mode %x", f->mode);
- printf("scratch1 %x", f->scratch1);
- printf("pad %x\n", f->pad);
- }
-}
-
-#if DDB
-inline int
-db_splhigh(void)
-{
- return (db_spln(6));
-}
-
-inline int
-db_splx(int s)
-{
- return (db_spln(s));
-}
-#endif /* DDB */
diff --git a/sys/arch/mvme88k/m88k/misc.s b/sys/arch/mvme88k/m88k/misc.s
deleted file mode 100644
index a627f6a28da..00000000000
--- a/sys/arch/mvme88k/m88k/misc.s
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 10:54:27 deraadt
- * Initial revision
- *
- * 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
diff --git a/sys/arch/mvme88k/m88k/pmap.c b/sys/arch/mvme88k/m88k/pmap.c
deleted file mode 100644
index adfdc4c5099..00000000000
--- a/sys/arch/mvme88k/m88k/pmap.c
+++ /dev/null
@@ -1,5538 +0,0 @@
-/*
- * HISTORY
- */
-
-/* don't want to make them general yet. */
-#ifdef luna88k
-# define OMRON_PMAP
-#endif
-# define OMRON_PMAP
-
-#include <sys/types.h>
-#include <machine/board.h>
-#include <vm/pmap.h>
-#include <machine/m882xx.h>/* CMMU stuff */
-#include <vm/vm_kern.h> /* vm/vm_kern.h */
-#include <assym.s>
-
-/*#ifdef luna88k*/
-# define splblock splhigh
-/*#endif */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/msgbuf.h>
-#include <machine/assert.h>
-
-
- /*
- * VM externals
- */
-extern vm_offset_t avail_start, avail_next, avail_end;
-extern vm_offset_t virtual_avail, virtual_end;
-
-#if 0
-/*
- * Machine configuration stuff
- */
-pmap_table_t pmap_table_build();
-#endif /* 0 */
-
-/*
- * Static variables, functions and variables for debugging
- */
-#ifdef DEBUG
-#define static
-
-boolean_t code_cache_enable = TRUE;
-boolean_t data_cache_enable = TRUE;
-boolean_t kernel_text_ro = FALSE; /* If TRUE kernel text set READ ONLY */
-
-/*
- * conditional debugging
- */
-
-#define CD_NORM 0x01
-#define CD_FULL 0x02
-
-#define CD_ACTIVATE 0x0000004 /* _pmap_activate */
-#define CD_KMAP 0x0000008 /* pmap_expand_kmap */
-#define CD_MAP 0x0000010 /* pmap_map */
-#define CD_MAPB 0x0000020 /* pmap_map_batc */
-#define CD_CACHE 0x0000040 /* pmap_cache_ctrl */
-#define CD_BOOT 0x0000080 /* pmap_bootstrap */
-#define CD_INIT 0x0000100 /* pmap_init */
-#define CD_CREAT 0x0000200 /* pmap_create */
-#define CD_FREE 0x0000400 /* pmap_free_tables */
-#define CD_DESTR 0x0000800 /* pmap_destroy */
-#define CD_RM 0x0001000 /* pmap_remove */
-#define CD_RMAL 0x0002000 /* pmap_remove_all */
-#define CD_COW 0x0004000 /* pmap_copy_on_write */
-#define CD_PROT 0x0008000 /* pmap_protect */
-#define CD_EXP 0x0010000 /* pmap_expand */
-#define CD_ENT 0x0020000 /* pmap_enter */
-#define CD_UPD 0x0040000 /* pmap_update */
-#define CD_COL 0x0080000 /* pmap_collect */
-#define CD_CMOD 0x0100000 /* pmap_clear_modify */
-#define CD_IMOD 0x0200000 /* pmap_is_modified */
-#define CD_CREF 0x0400000 /* pmap_clear_reference */
-#define CD_PGMV 0x0800000 /* pagemove */
-#define CD_CHKPV 0x1000000 /* check_pv_list */
-#define CD_CHKPM 0x2000000 /* check_pmap_consistency */
-#define CD_CHKM 0x4000000 /* check_map */
-#define CD_ALL 0x0FFFFFC
-
-int pmap_con_dbg = CD_FULL|CD_NORM;
-
-#endif /* DBG */
-
-int cmmumap = 0;
-int mapallio = 1;
-int mapextra = 1;
-int mydebug = 0;
-extern proc0paddr;
-
-/*
- * All those kernel PT submaps that BSD is so fond of
- */
-caddr_t CADDR1, CADDR2, vmmap;
-u_int *CMAP1, *CMAP2, *vmpte, *msgbufmap;
-
-/*
- * PHYS_TO_VM_PAGE and vm_page_set_modified, called by pmap_remove_range
- * and pmap_remove_all, are still stubbed out.
- *
- * VM-routines would keep truck of the page status through calling
- * pmap_is_modified.
- */
-
-#ifndef PHYS_TO_VM_PAGE
-#define PHYS_TO_VM_PAGE(pa)
-#endif
-
-#ifndef vm_page_set_modified
-#define vm_page_set_modified(m)
-#endif
-
-static struct pmap kernel_pmap_store;
-pmap_t kernel_pmap = &kernel_pmap_store;
-
-typedef struct kpdt_entry *kpdt_entry_t;
-struct kpdt_entry {
- kpdt_entry_t next;
- vm_offset_t phys;
-};
-#define KPDT_ENTRY_NULL ((kpdt_entry_t)0)
-
-static kpdt_entry_t kpdt_free;
-
-/*
- * MAX_KERNEL_VA_SIZE must be fit into the virtual address space between
- * VM_MIN_KERNEL_ADDRESS and VM_MAX_KERNEL_ADDRESS.
- */
-#define MAX_KERNEL_VA_SIZE (256*1024*1024)
-
-
-/*
- * Size of kernel page tables, which is enough to map MAX_KERNEL_VA_SIZE
- */
-#define MAX_KERNEL_PDT_SIZE (M88K_BTOP(MAX_KERNEL_VA_SIZE) * sizeof(pt_entry_t))
-
-
-/*
- * Two pages of scratch space.
- * Used in copy_to_phys(), pmap_copy_page() and pmap_zero_page().
- */
-vm_offset_t phys_map_vaddr1, phys_map_vaddr2;
-
-int ptes_per_vm_page; /* number of M88K ptes required to map one VM page */
-
-
-#define PMAP_MAX 512
-
-/*
- * The Modify List
- *
- * This is an array, one byte per physical page, which keeps track
- * of modified flags for pages which are no longer containd in any
- * pmap. (for mapped pages, the modified flags are in the PTE.)
- */
-char *pmap_modify_list;
-
-
-/* The PV (Physical to virtual) List.
- *
- * For each vm_page_t, pmap keeps a list of all currently valid virtual
- * mappings of that page. An entry is a pv_entry_t; the list is the pv_table.
- * This is used by things like pmap_remove, when we must find and remove all
- * mappings for a particular physical page.
- */
-typedef struct pv_entry {
- struct pv_entry *next; /* next pv_entry */
- pmap_t pmap; /* pmap where mapping lies */
- vm_offset_t va; /* virtual address for mapping */
-} *pv_entry_t;
-
-#define PV_ENTRY_NULL ((pv_entry_t) 0)
-
-static pv_entry_t pv_head_table; /* array of entries, one per page */
-
-/*
- * Index into pv_head table, its lock bits, and the modify bits
- * starting at pmap_phys_start.
- */
-#define PFIDX(pa) (atop(pa - pmap_phys_start))
-#define PFIDX_TO_PVH(pfidx) (&pv_head_table[pfidx])
-
-
-/*
- * Locking and TLB invalidation primitives
- */
-
-/*
- * Locking Protocols:
- *
- * There are two structures in the pmap module that need locking:
- * the pmaps themselves, and the per-page pv_lists (which are locked
- * by locking the pv_lock_table entry that corresponds to the pv_head
- * for the list in question.) Most routines want to lock a pmap and
- * then do operations in it that require pv_list locking -- however
- * pmap_remove_all and pmap_copy_on_write operate on a physical page
- * basis and want to do the locking in the reverse order, i.e. lock
- * a pv_list and then go through all the pmaps referenced by that list.
- * To protect against deadlock between these two cases, the pmap_lock
- * is used. There are three different locking protocols as a result:
- *
- * 1. pmap operations only (pmap_extract, pmap_access, ...) Lock only
- * the pmap.
- *
- * 2. pmap-based operations (pmap_enter, pmap_remove, ...) Get a read
- * lock on the pmap_lock (shared read), then lock the pmap
- * and finally the pv_lists as needed [i.e. pmap lock before
- * pv_list lock.]
- *
- * 3. pv_list-based operations (pmap_remove_all, pmap_copy_on_write, ...)
- * Get a write lock on the pmap_lock (exclusive write); this
- * also guaranteees exclusive access to the pv_lists. Lock the
- * pmaps as needed.
- *
- * At no time may any routine hold more than one pmap lock or more than
- * one pv_list lock. Because interrupt level routines can allocate
- * mbufs and cause pmap_enter's, the pmap_lock and the lock on the
- * kernel_pmap can only be held at splvm.
- */
-/* DCR: 12/18/91 - The above explanation is no longer true. The pmap
- * system lock has been removed in favor of a backoff strategy to
- * avoid deadlock. Now, pv_list-based operations first get the
- * pv_list lock, then try to get the pmap lock, but if they can't,
- * they release the pv_list lock and retry the whole operation.
- */
-
-#define SPLVM(spl) { spl = splvm(); }
-#define SPLX(spl) { splx(spl); }
-
-#define PMAP_LOCK(pmap, spl) SPLVM(spl)
-#define PMAP_UNLOCK(pmap, spl) SPLX(spl)
-
-#define PV_LOCK_TABLE_SIZE(n) 0
-#define LOCK_PVH(index)
-#define UNLOCK_PVH(index)
-
-/*
- * First and last physical address that we maintain any information
- * for. Initalized to zero so that pmap operations done before
- * pmap_init won't touch any non-existent structures.
- */
-
-static vm_offset_t pmap_phys_start = (vm_offset_t) 0;
-static vm_offset_t pmap_phys_end = (vm_offset_t) 0;
-
-#define PMAP_MANAGED(pa) ((pa) >= pmap_phys_start && (pa) < pmap_phys_end)
-
-/*
- * This variable extract vax's pmap.c.
- * pmap_verify_free refer to this.
- * pmap_init initialize this.
- * '90.7.17 Fuzzy
- */
-boolean_t pmap_initialized = FALSE;/* Has pmap_init completed? */
-
-/*
- * Consistency checks.
- * These checks are disabled by default; enabled by setting CD_FULL
- * in pmap_con_dbg.
- */
-#ifdef DEBUG
-#define CHECK_PV_LIST(phys,pv_h,who) \
- if (pmap_con_dbg & CD_CHKPV) check_pv_list(phys,pv_h,who)
-#define CHECK_PMAP_CONSISTENCY(who) \
- if (pmap_con_dbg & CD_CHKPM) check_pmap_consistency(who)
-#else
-#define CHECK_PV_LIST(phys,pv_h,who)
-#define CHECK_PMAP_CONSISTENCY(who)
-#endif /* DEBUG */
-
-/*
- * number of BATC entries used
- */
-int batc_used;
-
-/*
- * keep track BATC mapping
- */
-batc_entry_t batc_entry[BATC_MAX];
-
-int maxcmmu_pb = 4; /* max number of CMMUs per processors pbus */
-int n_cmmus_pb = 1; /* number of CMMUs per processors pbus */
-
-#define cpu_number() 0 /* just being lazy, should be taken out -nivas*/
-
-vm_offset_t kmapva = 0;
-
-static void flush_atc_entry(unsigned users, vm_offset_t va, int kernel)
-{
- /* always flush cpu 0 TLB till we understand if this
- is required XXX -nivas */
-/* if (users) */
- cmmu_flush_remote_tlb(cpu_number(), kernel, va, M88K_PGBYTES);
-}
-
-/*
- * Routine: _PMAP_ACTIVATE
- *
- * Author: N. Sugai
- *
- * Function:
- * Binds the given physical map to the given processor.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * p pointer to proc structure
- * cpu CPU number
- *
- * If the specified pmap is not kernel_pmap, this routine makes arp
- * template and stores it into UAPR (user area pointer register) in the
- * CMMUs connected to the specified CPU.
- *
- * If kernel_pmap is specified, only flushes the TLBs mapping kernel
- * virtual space, in the CMMUs connected to the specified CPU.
- *
- * NOTE:
- * All of the code of this function extracted from macro PMAP_ACTIVATE
- * to make debugging easy. Accordingly, PMAP_ACTIVATE simlpy call
- * _pmap_activate.
- *
- */
-void
-_pmap_activate(
- register pmap_t pmap,
- register pcb_t pcb,
- register int my_cpu)
-{
- register apr_template_t apr_data;
- register int n;
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_ACTIVATE | CD_FULL)) == (CD_ACTIVATE | CD_NORM))
- printf("(_pmap_activate :%x) pmap 0x%x\n", curproc, (unsigned)pmap);
-#endif
-
- if (pmap != kernel_pmap) {
- /*
- * Lock the pmap to put this cpu in its active set.
- */
- simple_lock(&pmap->lock);
-
- apr_data.bits = 0;
- apr_data.field.st_base = M88K_BTOP(pmap->sdt_paddr);
- apr_data.field.wt = 0;
- apr_data.field.g = 1;
- apr_data.field.ci = 0;
- apr_data.field.te = 1;
-#ifdef OMRON_PMAP
- /*
- * cmmu_pmap_activate will set the uapr and the batc entries, then
- * flush the *USER* TLB. IF THE KERNEL WILL EVER CARE ABOUT THE
- * BATC ENTRIES, THE SUPERVISOR TLBs SHOULB BE FLUSHED AS WELL.
- */
- cmmu_pmap_activate(my_cpu, apr_data.bits, pmap->i_batc, pmap->d_batc);
- for (n = 0; n < BATC_MAX; n++)
- *(unsigned*)&batc_entry[n] = pmap->i_batc[n].bits;
-#else
- cmmu_set_uapr(apr_data.bits);
- cmmu_flush_tlb(0, 0, -1);
-#endif
-
- /*
- * Mark that this cpu is using the pmap.
- */
- simple_unlock(&pmap->lock);
-
- } else {
-
- /*
- * kernel_pmap must be always active.
- */
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_ACTIVATE | CD_NORM)) == (CD_ACTIVATE | CD_NORM))
- printf("(_pmap_activate :%x) called for kernel_pmap\n", curproc);
-#endif
-
- }
-} /* _pmap_activate */
-
-/*
- * Routine: _PMAP_DEACTIVATE
- *
- * Author: N. Sugai
- *
- * Function:
- * Unbinds the given physical map to the given processor.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * th pointer to thread structure
- * cpu CPU number
- *
- * _pmap_deactive simply clears the cpus_using field in given pmap structure.
- *
- * NOTE:
- * All of the code of this function extracted from macro PMAP_DEACTIVATE
- * to make debugging easy. Accordingly, PMAP_DEACTIVATE simlpy call
- * _pmap_deactivate.
- *
- */
-void
-_pmap_deactivate(
- register pmap_t pmap,
- register pcb_t pcb,
- register int my_cpu)
-{
- if (pmap != kernel_pmap) {
- /* Nothing to do */
- }
-}
-
-/*
- * Author: Joe Uemura
- * Convert machine-independent protection code to M88K protection bits.
- *
- * History:
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- */
-
-static int unsigned m88k_protection(
- pmap_t map,
- vm_prot_t prot)
-{
- register pte_template_t p;
-
- p.bits = 0;
- p.pte.prot = (prot & VM_PROT_WRITE) ? 0 : 1;
-
- return(p.bits);
-
-} /* m88k_protection */
-
-
-/*
- * Routine: PMAP_PTE
- *
- * Author: Joe Uemura
- *
- * Function:
- * Given a map and a virtual address, compute a (virtual) pointer
- * to the page table entry (PTE) which maps the address .
- * If the page table associated with the address does not
- * exist, PT_ENTRY_NULL is returned (and the map may need to grow).
- *
- * Parameters:
- * pmap pointer to pmap structure
- * virt virtual address for which page table entry is desired
- *
- * Otherwise the page table address is extracted from the segment table,
- * the page table index is added, and the result is returned.
- *
- * Calls:
- * SDTENT
- * SDT_VALID
- * PDT_IDX
- *
- * History:
- * 90/9/12 Fuzzy if pmap == PMAP_NULL, panic
- */
-pt_entry_t * pmap_pte(
- pmap_t map,
- vm_offset_t virt)
-{
- sdt_entry_t *sdt;
-
- if (map == PMAP_NULL)
- panic("pmap_pte: pmap is NULL");
-
- sdt = SDTENT(map,virt);
-
- /*
- * Check whether page table is exist or not.
- */
- if (!SDT_VALID(sdt))
- return(PT_ENTRY_NULL);
- else
- return((pt_entry_t *)(((sdt + SDT_ENTRIES)->table_addr)<<PDT_SHIFT) + PDTIDX(virt));
-
-} /* pmap_pte */
-
-
-/*
- * Routine: PMAP_EXPAND_KMAP (internal)
- *
- * History:
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.27 Fuzzy
- * allocated pte entry clear
- * '90.8.28 Fuzzy
- * Bug: No free kernel page table process
- * panic("pmap_expand_kmap:...");
- * --> #ifdef DBG
- * printf("Warnning: Ran out of page table entry VALID\n");
- * #endif
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- * Author: Fuzzy
- *
- * Function:
- * Allocate a page descriptor table (pte_table) and validate associated
- * segment table entry, returning pointer to page table entry. This is
- * much like 'pmap_expand', except that table space is acquired
- * from an area set up by pmap_bootstrap, instead of through
- * kmem_alloc. (Obviously, because kmem_alloc uses the kernel map
- * for allocation - which we can't do when trying to expand the
- * kernel map!) Note that segment tables for the kernel map were
- * all allocated at pmap_bootstrap time, so we only need to worry
- * about the page table here.
- *
- * Parameters:
- * virt VA for which translation tables are needed
- * prot protection attributes for segment entries
- *
- * Extern/Global:
- * kpdt_free kernel page table free queue
- *
- * Calls:
- * m88k_protection
- * SDTENT
- * SDT_VALID
- * PDT_IDX
- *
- * This routine simply dequeues a table from the kpdt_free list,
- * initalizes all its entries (invalidates them), and sets the
- * corresponding segment table entry to point to it. If the kpdt_free
- * list is empty - we panic (no other places to get memory, sorry). (Such
- * a panic indicates that pmap_bootstrap is not allocating enough table
- * space for the kernel virtual address space).
- *
- */
-
-static pt_entry_t * pmap_expand_kmap(
- vm_offset_t virt,
- vm_prot_t prot)
-{
- int aprot;
- sdt_entry_t *sdt;
- kpdt_entry_t kpdt_ent;
- pmap_t map = kernel_pmap;
-
-#if DEBUG
- if ((pmap_con_dbg & (CD_KMAP | CD_FULL)) == (CD_KMAP | CD_FULL))
- printf("(pmap_expand_kmap :%x) v %x\n", curproc,virt);
-#endif
-
- aprot = m88k_protection (map, prot);
-
- /* segment table entry derivate from map and virt. */
- sdt = SDTENT(map, virt);
- if (SDT_VALID(sdt))
- panic("pmap_expand_kmap: segment table entry VALID");
-
- kpdt_ent = kpdt_free;
- if (kpdt_ent == KPDT_ENTRY_NULL) {
- printf("pmap_expand_kmap: Ran out of kernel pte tables\n");
- return(PT_ENTRY_NULL);
- }
- kpdt_free = kpdt_free->next;
-
- ((sdt_entry_template_t *)sdt)->bits = kpdt_ent->phys | aprot | DT_VALID;
- ((sdt_entry_template_t *)(sdt + SDT_ENTRIES))->bits = (vm_offset_t)kpdt_ent | aprot | DT_VALID;
- (unsigned)(kpdt_ent->phys) = 0;
- (unsigned)(kpdt_ent->next) = 0;
-
- return((pt_entry_t *)(kpdt_ent) + PDTIDX(virt));
-}/* pmap_expand_kmap() */
-
-/*
- * Routine: PMAP_MAP
- *
- * Function:
- * Map memory at initalization. The physical addresses being
- * mapped are not managed and are never unmapped.
- *
- * Parameters:
- * virt virtual address of range to map (IN)
- * start physical address of range to map (IN)
- * end physical address of end of range (IN)
- * prot protection attributes (IN)
- *
- * Calls:
- * pmap_pte
- * pmap_expand_kmap
- *
- * Special Assumptions
- * For now, VM is already on, only need to map the specified
- * memory. Used only by pmap_bootstrap() and vm_page_startup().
- *
- * For each page that needs mapping:
- * pmap_pte is called to obtain the address of the page table
- * table entry (PTE). If the page table does not exist,
- * pmap_expand_kmap is called to allocate it. Finally, the page table
- * entry is set to point to the physical page.
- *
- *
- * initialize template with paddr, prot, dt
- * look for number of phys pages in range
- * {
- * pmap_pte(virt) - expand if necessary
- * stuff pte from template
- * increment virt one page
- * increment template paddr one page
- * }
- *
- *
- * History:
- * 90/09/12 Fuzzy calculation of allocating page table entry number
- * 90/09/12 Fuzzy When mapped VA map again, output warinning message.
- *
- */
-vm_offset_t pmap_map(
- register vm_offset_t virt,
- register vm_offset_t start,
- register vm_offset_t end,
- register vm_prot_t prot
-#ifdef OMRON_PMAP
- , register unsigned cmode
-#endif /* OMRON */
- )
-{
- int aprot;
- unsigned npages;
- unsigned num_phys_pages;
- pt_entry_t *pte;
- pte_template_t template;
-
-#if DEBUG
- if ((pmap_con_dbg & (CD_MAP | CD_FULL)) == (CD_MAP | CD_FULL))
- printf ("(pmap_map :%x) phys address from %x to %x mapped at virtual %x, prot %x\n",
- curproc, start, end, virt, prot);
-#endif
-
- if (start > end)
- panic("pmap_map: start greater than end address");
-
- aprot = m88k_protection (kernel_pmap, prot);
-
-#ifdef OMRON_PMAP
- template.bits = M88K_TRUNC_PAGE(start) | aprot | DT_VALID | cmode;
-#else /* OMRON */
- template.bits = M88K_TRUNC_PAGE(start) | aprot | DT_VALID;
-#endif /* OMRON */
-
- npages = M88K_BTOP(M88K_ROUND_PAGE(end) - M88K_TRUNC_PAGE(start));
-
- for (num_phys_pages = npages; num_phys_pages > 0; num_phys_pages--) {
-
- if ((pte = pmap_pte(kernel_pmap, virt)) == PT_ENTRY_NULL)
- if ((pte = pmap_expand_kmap(virt, VM_PROT_READ|VM_PROT_WRITE)) == PT_ENTRY_NULL)
- panic ("pmap_map: Cannot allocate pte table");
-
-#ifdef DEBUG
- if (pmap_con_dbg & CD_MAP)
- if (pte->dtype)
- printf("(pmap_map :%x) pte @ 0x%x already valid\n", curproc, (unsigned)pte);
-#endif
-
- *pte = template.pte;
- virt += M88K_PGBYTES;
- template.bits += M88K_PGBYTES;
- }
-
- return(virt);
-
-} /* pmap_map() */
-
-/*
- * Routine: PMAP_MAP_BATC
- *
- * Function:
- * Map memory using BATC at initalization. The physical addresses being
- * mapped are not managed and are never unmapped.
- *
- * Parameters:
- * virt virtual address of range to map (IN)
- * start physical address of range to map (IN)
- * end physical address of end of range (IN)
- * prot protection attributes (IN)
- * cmode cache control attributes (IN)
- *
- * External & Global:
- * batc_used number of BATC used (IN/OUT)
- *
- * Calls:
- * m88k_protection
- * BATC_BLK_ALIGNED
- * cmmu_store
- * pmap_pte
- * pmap_expand_kmap
- *
- *
- * For each page that needs mapping:
- * If both virt and phys are on the BATC block boundary, map using BATC.
- * Else make mapping in the same manner as pmap_map.
- *
- * initialize BATC and pte template
- * look for number of phys pages in range
- * {
- * if virt and phys are on BATC block boundary
- * {
- * map using BATC
- * increment virt and phys one BATC block
- * continue outer loop
- * }
- * pmap_pte(virt) - expand if necessary
- * stuff pte from template
- * increment virt one page
- * increment template paddr one page
- * }
- *
- * Author: Sugai
- * Oct 25 '90 Initial virsion
- *
- */
-vm_offset_t
-pmap_map_batc (
- register vm_offset_t virt,
- register vm_offset_t start,
- register vm_offset_t end,
- register vm_prot_t prot,
- register unsigned cmode)
-{
- int aprot;
- unsigned num_phys_pages;
- vm_offset_t phys;
- pt_entry_t *pte;
- pte_template_t template;
- batc_template_t batctmp;
- register int i;
-
-#if DEBUG
- if ((pmap_con_dbg & (CD_MAPB | CD_FULL)) == (CD_MAPB | CD_FULL))
- printf ("(pmap_map_batc :%x) phys address from %x to %x mapped at virtual %x, prot %x\n", curproc,
- start, end, virt, prot);
-#endif
-
- if (start > end)
- panic("pmap_map_batc: start greater than end address");
-
- aprot = m88k_protection (kernel_pmap, prot);
- template.bits = M88K_TRUNC_PAGE(start) | aprot | DT_VALID | cmode;
- phys = start;
- batctmp.bits = 0;
- batctmp.field.sup = 1; /* supervisor */
- batctmp.field.wt = template.pte.wt; /* write through */
- batctmp.field.g = template.pte.g; /* global */
- batctmp.field.ci = template.pte.ci; /* cache inhibit */
- batctmp.field.wp = template.pte.prot; /* protection */
- batctmp.field.v = 1; /* valid */
-
- num_phys_pages = M88K_BTOP(M88K_ROUND_PAGE(end) - M88K_TRUNC_PAGE(start));
-
- while (num_phys_pages > 0) {
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_MAPB | CD_FULL)) == (CD_MAPB | CD_FULL))
- printf("(pmap_map_batc :%x) num_phys_pg=%x, virt=%x, aligne V=%d, phys=%x, aligne P=%d\n", curproc,
- num_phys_pages, virt, BATC_BLK_ALIGNED(virt), phys, BATC_BLK_ALIGNED(phys));
-#endif
-
- if ( BATC_BLK_ALIGNED(virt) && BATC_BLK_ALIGNED(phys) &&
- num_phys_pages >= BATC_BLKBYTES/M88K_PGBYTES &&
- batc_used < BATC_MAX ) {
-
- /*
- * map by BATC
- */
- batctmp.field.lba = M88K_BTOBLK(virt);
- batctmp.field.pba = M88K_BTOBLK(phys);
-
- cmmu_set_pair_batc_entry(0, batc_used, batctmp.bits);
-
- batc_entry[batc_used] = batctmp.field;
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_MAPB | CD_NORM)) == (CD_MAPB | CD_NORM)) {
- printf("(pmap_map_batc :%x) BATC used=%d, data=%x\n", curproc, batc_used, batctmp.bits);
- }
- if (pmap_con_dbg & CD_MAPB) {
-
- for (i = 0; i < BATC_BLKBYTES; i += M88K_PGBYTES ) {
- pte = pmap_pte(kernel_pmap, virt+i);
- if (pte->dtype)
- printf("(pmap_map_batc :%x) va %x is already mapped : pte %x\n", curproc, virt+i, ((pte_template_t *)pte)->bits);
- }
- }
-#endif
- batc_used++;
- virt += BATC_BLKBYTES;
- phys += BATC_BLKBYTES;
- template.pte.pfn = M88K_BTOP(phys);
- num_phys_pages -= BATC_BLKBYTES/M88K_PGBYTES;
- continue;
- }
- if ((pte = pmap_pte(kernel_pmap, virt)) == PT_ENTRY_NULL)
- if ((pte = pmap_expand_kmap(virt, VM_PROT_READ|VM_PROT_WRITE)) == PT_ENTRY_NULL)
- panic ("pmap_map_batc: Cannot allocate pte table");
-
-#ifdef DEBUG
- if (pmap_con_dbg & CD_MAPB)
- if (pte->dtype)
- printf("(pmap_map_batc :%x) pte @ 0x%x already valid\n", curproc, (unsigned)pte);
-#endif
-
- *pte = template.pte;
- virt += M88K_PGBYTES;
- phys += M88K_PGBYTES;
- template.bits += M88K_PGBYTES;
- num_phys_pages--;
- }
-
- return(M88K_ROUND_PAGE(virt));
-
-} /* pmap_map_batc() */
-
-/*
- * Routine: PMAP_CACHE_CONTROL
- *
- * Author: Sugai 90/09/07
- *
- * Function:
- * Set the cache-control bits in the page table entries(PTE) which maps
- * the specifid virutal address range.
- *
- * mode
- * writethrough 0x200
- * global 0x80
- * cache inhibit 0x40
- *
- * Parameters:
- * pmap_t map
- * vm_offset_t s
- * vm_offset_t e
- * unsigned mode
- *
- * Calls:
- * PMAP_LOCK
- * PMAP_UNLOCK
- * pmap_pte
- * invalidate_pte
- * flush_atc_entry
- * dcachefall
- *
- * This routine sequences through the pages of the specified range.
- * For each, it calls pmap_pte to acquire a pointer to the page table
- * entry (PTE). If the PTE is invalid, or non-existant, nothing is done.
- * Otherwise, the cache-control bits in the PTE's are adjusted as specified.
- *
- */
-void pmap_cache_ctrl(
- pmap_t pmap,
- vm_offset_t s,
- vm_offset_t e,
- unsigned mode)
-{
- int spl, spl_sav;
- pt_entry_t *pte;
- vm_offset_t va;
- int kflush;
- int cpu;
- register pte_template_t opte;
-
-#ifdef DEBUG
- if ( mode & CACHE_MASK ) {
- printf("(cache_ctrl) illegal mode %x\n",mode);
- return;
- }
- if ((pmap_con_dbg & (CD_CACHE | CD_NORM)) == (CD_CACHE | CD_NORM)) {
- printf("(pmap_cache_ctrl :%x) pmap %x, va %x, mode %x\n", curproc, pmap, s, mode);
- }
-#endif /* DEBUG */
-
- if ( pmap == PMAP_NULL ) {
- panic("pmap_cache_ctrl: pmap is NULL");
- }
-
- PMAP_LOCK(pmap, spl);
-
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- for (va = s; va < e; va += M88K_PGBYTES) {
- if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
- continue;
-#ifdef DEBUG
- printf("(cache_ctrl) pte@0x%08x\n",(unsigned)pte);
-#endif /* DEBUG */
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- * XXX
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- ((pte_template_t *)pte)->bits = (opte.bits & CACHE_MASK) | mode;
- flush_atc_entry(0, va, kflush);
- splx(spl_sav);
-
- /*
- * Data cache should be copied back and invalidated.
- */
- cmmu_flush_remote_cache(0, M88K_PTOB(pte->pfn), M88K_PGBYTES);
- }
-
- PMAP_UNLOCK(pmap, spl);
-
-} /* pmap_cache_ctrl */
-
-
-/*
- * Routine: PMAP_BOOTSTRAP
- *
- * Author: Fuzzy '90.7.12
- *
- * 90.7.23. JU - changed blkclr to bzero
- *
- *
- * Function:
- * Bootstarp the system enough to run with virtual memory.
- * Map the kernel's code and data, allocate the kernel
- * translation table space, and map control registers
- * and other IO addresses.
- *
- * Parameters:
- * load_start PA where kernel was loaded (IN)
- * &phys_start PA of first available physical page (IN/OUT)
- * &phys_end PA of last available physical page (IN)
- * &virtual_avail VA of first available page (after kernel bss)
- * &virtual_end VA of last available page (end of kernel address space)
- *
- * Extern/Global:
- *
- * PAGE_SIZE VM (software) page size (IN)
- * kernelstart start symbol of kernel text (IN)
- * etext end of kernel text (IN)
- * phys_map_vaddr1 VA of page mapped arbitrarily for debug/IO (OUT)
- * phys_map_vaddr2 VA of page mapped arbitrarily for debug/IO (OUT)
- *
- * Calls:
- * simple_lock_init
- * pmap_map
- * pmap_map_batc
- *
- * The physical address 'load_start' is mapped at
- * VM_MIN_KERNEL_ADDRESS, which maps the kernel code and data at the
- * virtual address for which it was (presumably) linked. Immediately
- * following the end of the kernel code/data, sufficent page of
- * physical memory are reserved to hold translation tables for the kernel
- * address space. The 'phys_start' parameter is adjusted upward to
- * reflect this allocation. This space is mapped in virtual memory
- * immediately following the kernel code/data map.
- *
- * A pair of virtual pages are reserved for debugging and IO
- * purposes. They are arbitrarily mapped when needed. They are used,
- * for example, by pmap_copy_page and pmap_zero_page.
- *
- * For m88k, we have to map BUG memory also. This is a read only
- * mapping for 0x10000 bytes. We will end up having load_start as
- * 0 and VM_MIN_KERNEL_ADDRESS as 0 - yes sir, we have one-to-one
- * mapping!!!
- */
-
-void
-pmap_bootstrap(
- vm_offset_t load_start, /* IN */
- vm_offset_t *phys_start, /* IN/OUT */
- vm_offset_t *phys_end, /* IN */
- vm_offset_t *virt_start, /* OUT */
- vm_offset_t *virt_end) /* OUT */
-{
- kpdt_entry_t kpdt_virt;
- sdt_entry_t *kmap;
- vm_offset_t vaddr,
- virt,
- kpdt_phys,
- s_text,
- e_text,
- kernel_pmap_size;
- apr_template_t apr_data;
- pt_entry_t *pte;
- int i;
- extern char *kernelstart, *etext;
-#if 0
- pmap_table_t ptable;
-#endif /* 0 */
-
- printf("pmap_bootstrap : \"load_start\" 0x%x\n", load_start);
- ptes_per_vm_page = PAGE_SIZE >> M88K_PGSHIFT;
- if (ptes_per_vm_page == 0)
- panic("pmap_bootstrap: VM page size < MACHINE page size");
-
- if ( ! PAGE_ALIGNED(load_start)) {
- printf("pmap_bootstrap : \"load_start\" not on the m88k page boundary : 0x%x\n", load_start);
- }
-
- /*
- * Allocate the kernel page table from the front of available
- * physical memory,
- * i.e. just after where the kernel image was loaded.
- */
- /*
- * The calling sequence is
- * ...
- * pmap_bootstrap(&kernelstart,...)
- * kernelstart is the first symbol in the load image.
- * We link the kernel such that &kernelstart == 0x10000 (size of
- * BUG ROM)
- * The expression (&kernelstart - load_start) will end up as
- * 0, making *virt_start == *phys_start, giving a 1-to-1 map)
- */
-
- *phys_start = M88K_ROUND_PAGE(*phys_start);
- *virt_start = *phys_start + ((unsigned)&kernelstart - GOOFYLDOFFSET - load_start);
-
- /*
- * Initialilze kernel_pmap structure
- */
- kernel_pmap->ref_count = 1;
- kernel_pmap->sdt_paddr = kmap = (sdt_entry_t *)(*phys_start);
- kernel_pmap->sdt_vaddr = (sdt_entry_t *)(*virt_start);
- kmapva = *virt_start;
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("kernel_pmap->sdt_paddr = %x\n",kernel_pmap->sdt_paddr);
- printf("kernel_pmap->sdt_vaddr = %x\n",kernel_pmap->sdt_vaddr);
- }
- /* init double-linked list of pmap structure */
- kernel_pmap->next = kernel_pmap;
- kernel_pmap->prev = kernel_pmap;
-#endif
-
- /*
- * Reserve space for segment table entries.
- * One for the regular segment table and one for the shadow table
- * The shadow table keeps track of the virtual address of page
- * tables. This is used in virtual-to-physical address translation
- * functions. Remember, MMU cares only for physical addresses of
- * segment and page table addresses. For kernel page tables, we
- * really don't need this virtual stuff (since the kernel will
- * be mapped 1-to-1) but for user page tables, this is required.
- * Just to be consistent, we will maintain the shadow table for
- * kernel pmap also.
- */
-
- kernel_pmap_size = 2*SDT_SIZE;
-
- /* save pointers to where page table entries start in physical memory */
- kpdt_phys = (*phys_start + kernel_pmap_size);
- kpdt_virt = (kpdt_entry_t)(*virt_start + kernel_pmap_size);
- kernel_pmap_size += MAX_KERNEL_PDT_SIZE;
- *phys_start += kernel_pmap_size;
- *virt_start += kernel_pmap_size;
-
- /* init all segment and page descriptor to zero */
- bzero(kernel_pmap->sdt_vaddr, kernel_pmap_size);
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("kpdt_phys = %x\n",kpdt_phys);
- printf("kpdt_virt = %x\n",kpdt_virt);
- printf("end of kpdt at (virt)0x%08x ; (phys)0x%08x\n",
- *virt_start,*phys_start);
- }
-#endif
- /*
- * init the kpdt queue
- */
- kpdt_free = kpdt_virt;
- for (i = MAX_KERNEL_PDT_SIZE/PDT_SIZE; i>0; i--) {
- kpdt_virt->next = (kpdt_entry_t)((vm_offset_t)kpdt_virt + PDT_SIZE);
- kpdt_virt->phys = kpdt_phys;
- kpdt_virt = kpdt_virt->next;
- kpdt_phys += PDT_SIZE;
- }
- kpdt_virt->next = KPDT_ENTRY_NULL; /* terminate the list */
-
- /*
- * Map the kernel image into virtual space
- */
-
- s_text = load_start; /* paddr of text */
- e_text = load_start + ((unsigned)&etext - (unsigned)&kernelstart - GOOFYLDOFFSET); /* paddr of end of text section*/
- e_text = M88K_ROUND_PAGE(e_text);
-
- #ifdef OMRON_PMAP
- #define PMAPER pmap_map
- #else
- #define PMAPER pmap_map_batc
- #endif
-
- /* map the first 64k (BUG ROM) read only, cache inhibited */
- vaddr = PMAPER(
- 0,
- 0,
- 0x10000,
- VM_PROT_READ|VM_PROT_WRITE,
- CACHE_INH);
-
- assert(vaddr == (unsigned)&kernelstart - GOOFYLDOFFSET);
-
- vaddr = PMAPER(
- (vm_offset_t)((unsigned)&kernelstart - GOOFYLDOFFSET),
- s_text,
- e_text,
- VM_PROT_WRITE | VM_PROT_READ, /* shouldn't it be RO? XXX*/
- CACHE_INH);
-
- vaddr = PMAPER(
- vaddr,
- e_text,
- (vm_offset_t)kmap,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_GLOBAL);
-
- /*
- * Map system segment & page tables - should be cache inhibited.
- */
- if (kmapva != vaddr) {
- printf("(pmap_bootstrap) correcting vaddr\n");
- while (vaddr < (*virt_start - kernel_pmap_size))
- vaddr = M88K_ROUND_PAGE(vaddr + 1);
- }
-
- vaddr = PMAPER(
- vaddr,
- (vm_offset_t)kmap,
- *phys_start,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_INH);
-
- if (vaddr != *virt_start) {
- *virt_start = vaddr;
- *phys_start = round_page(*phys_start);
- }
-
-
- *virt_start = round_page(*virt_start);
- *virt_end = VM_MAX_KERNEL_ADDRESS;
-
- /*
- * Map a few more pages for phys routines and debugger.
- */
-
- phys_map_vaddr1 = round_page(*virt_start);
- phys_map_vaddr2 = phys_map_vaddr1 + PAGE_SIZE;
-
- /*
- * To make 1:1 mapping of virt:phys, throw away a few phys pages
- */
-
- *phys_start += 2 * PAGE_SIZE;
- *virt_start += 2 * PAGE_SIZE;
-
- /*
- * establish mapping for code and data cmmu
- */
-
- if (cmmumap) {
- PMAPER(
- CMMU_I,
- CMMU_I,
- CMMU_I + 0x1000,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_INH);
-
- PMAPER(
- CMMU_D,
- CMMU_D,
- CMMU_D + 0x1000,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_INH);
- }
-#if 0
- if (mapextra) {
- PMAPER(
- 0x01000000,
- 0x01000000,
- 0x02000000,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_INH);
- }
-#endif /* 0 */
- if (mapallio) {
- PMAPER(
- 0xFF800000,
- 0xFF800000,
- 0xFFFF0000,
- VM_PROT_WRITE|VM_PROT_READ,
- CACHE_INH);
- }
-
-#if 0
- ptable = pmap_table_build(avail_end);
-
- for ( ; ptable->size != 0xffffffffU; ptable++)
- if (ptable->size)
- PMAPER(ptable->virt_start,
- ptable->phys_start,
- ptable->phys_start + ptable->size,
- ptable->prot,
- ptable->cacheability);
-
-#endif /* 0 */
-
- /*
- * Allocate all the submaps we need
- */
-#define SYSMAP(c, p, v, n) \
-({ \
- v = (c)virt; \
- if ((p = pmap_pte(kernel_pmap, virt)) == PT_ENTRY_NULL) \
- pmap_expand_kmap(virt, VM_PROT_READ|VM_PROT_WRITE); \
- virt += ((n)*NBPG); \
-})
-
- virt = *virt_start;
-
- SYSMAP(caddr_t ,CMAP1 ,CADDR1 ,1 );
- SYSMAP(caddr_t ,CMAP2 ,CADDR2 ,1 );
- SYSMAP(caddr_t ,vmpte ,vmmap ,1 );
- SYSMAP(struct msgbuf * ,msgbufmap ,msgbufp ,1 );
-
- *virt_start = virt;
- /*
- * Set translation for UPAGES at UADDR. The idea is we want to
- * have translations set up for UADDR. Later on, the ptes for
- * for this address will be set so that kstack will refer
- * to the u area. Make sure pmap knows about this virtual
- * address by doing vm_findspace on kernel_map.
- */
-
- for (i = 0, virt = UADDR; i < UPAGES; i++, virt += PAGE_SIZE) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("setting up mapping for Upage %d @ %x\n", i, virt);
- }
-#endif
- if ((pte = pmap_pte(kernel_pmap, virt)) == PT_ENTRY_NULL)
- pmap_expand_kmap(virt, VM_PROT_READ|VM_PROT_WRITE);
- }
- /*
- * Switch to using new page tables
- */
- apr_data.bits = 0;
- apr_data.field.st_base = M88K_BTOP(kernel_pmap->sdt_paddr);
- apr_data.field.wt = 1;
- apr_data.field.g = 1;
- apr_data.field.ci = 1;
- apr_data.field.te = 1; /* Translation enable */
-
- /* Invalidate entire kernel TLB. */
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("invalidating tlb %x\n", apr_data.bits);
- }
-#endif
- cmmu_flush_remote_tlb(0, 1, 0, -1);
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("done invalidating tlb %x\n", apr_data.bits);
- }
-#endif
-
- if (mydebug) {
- pmap_print(kernel_pmap);
- pmap_print_trace(kernel_pmap, (vm_offset_t)0xFFF00000, 1);
- }
- /* still physical */
- /* Load supervisor pointer to segment table. */
- cmmu_remote_set_sapr(0, apr_data.bits);
- /* virtual now on */
-#ifdef DEBUG
- printf("running virtual - avail_next 0x%x\n", *phys_start);
-#endif
- avail_next = *phys_start;
- if (mydebug) {
- pmap_print_trace(kernel_pmap, proc0paddr, 1);
- }
-
-} /* pmap_bootstrap() */
-
-/*
- * Bootstrap memory allocator. This function allows for early dynamic
- * memory allocation until the virtual memory system has been bootstrapped.
- * After that point, either kmem_alloc or malloc should be used. This
- * function works by stealing pages from the (to be) managed page pool,
- * stealing virtual address space, then mapping the pages and zeroing them.
- *
- * It should be used from pmap_bootstrap till vm_page_startup, afterwards
- * it cannot be used, and will generate a panic if tried. Note that this
- * memory will never be freed, and in essence it is wired down.
- */
-
-void *
-pmap_bootstrap_alloc(int size)
-{
- register void *mem;
-
- size = round_page(size);
- mem = (void *)virtual_avail;
- virtual_avail = pmap_map(virtual_avail, avail_start,
- avail_start + size, VM_PROT_READ|VM_PROT_WRITE, CACHE_INH);
- avail_start += size;
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_BOOT | CD_FULL)) == (CD_BOOT | CD_FULL)) {
- printf("pmap_bootstrap_alloc: size %x virtual_avail %x avail_start %x\n",
- size, virtual_avail, avail_start);
- }
-#endif
- bzero((void *)mem, size);
- return (mem);
-}
-
-/*
- * Routine: PMAP_INIT
- *
- * History
- * June 13 90 Fri. Fuzzy
- * Rewrite lvl1 --> segment
- * lvl3 --> page
- * '90.7.19 Fuzzy sdt_zone unused
- *
- * Function:
- * Initialize the pmap module. It is called by vm_init, to initialize
- * any structures that the pmap system needs to map virtual memory.
- *
- * Parameters:
- * phys_start physical address of first available page
- * (was last set by pmap_bootstrap)
- * phys_end physical address of last available page
- *
- * Extern/Globals
- * pv_head_table (OUT)
- * pv_lock_table (OUT)
- * pmap_modify_list (OUT)
- * pmap_phys_start (OUT)
- * pmap_phys_end (OUT)
- * pmap_initialized(OUT)
- *
- * Calls:
- * kmem_alloc
- * zinit
- *
- * This routine does not really have much to do. It allocates space
- * for the pv_head_table, pv_lock_table, pmap_modify_list; and sets these
- * pointers. It also initializes zones for pmap structures, pv_entry
- * structures, and segment tables.
- *
- * Last, it sets the pmap_phys_start and pmap_phys_end global
- * variables. These define the range of pages 'managed' be pmap. These
- * are pages for which pmap must maintain the PV list and the modify
- * list. (All other pages are kernel-specific and are permanently
- * wired.)
- *
- *
- * kmem_alloc() memory for pv_table
- * kmem_alloc() memory for modify_bits
- * zinit(pmap_zone)
- * zinit(segment zone)
- *
- */
-void pmap_init(vm_offset_t phys_start, vm_offset_t phys_end)
-{
- register long npages;
- register vm_offset_t addr;
- register vm_size_t s;
- register int i;
- vm_size_t pvl_table_size;
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_INIT | CD_NORM)) == (CD_INIT | CD_NORM))
- printf("(pmap_init) phys_start %x phys_end %x\n", phys_start, phys_end);
-#endif
-
- /*
- * Allocate memory for the pv_head_table,
- * the modify bit array, and the pte_page table.
- */
- npages = atop(phys_end - phys_start);
- pvl_table_size = PV_LOCK_TABLE_SIZE(npages);
- s = (vm_size_t)(npages * sizeof(struct pv_entry) /* pv_list */
- #if 0
- + pvl_table_size /* pv_lock_table */
- #endif /* 0 */
- + npages); /* pmap_modify_list */
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_INIT | CD_FULL)) == (CD_INIT | CD_FULL)) {
- printf("(pmap_init) nbr of managed pages = %x\n", npages);
- printf("(pmap_init) size of pv_list = %x\n",
- npages * sizeof(struct pv_entry));
- }
-#endif
-
- s = round_page(s);
- addr = (vm_offset_t)kmem_alloc(kernel_map, s);
-
- pv_head_table = (pv_entry_t)addr;
- addr = (vm_offset_t)(pv_head_table + npages);
-
- pmap_modify_list = (char *)addr;
-
- /*
- * Only now, when all of the data structures are allocated,
- * can we set pmap_phys_start and pmap_phys_end. If we set them
- * too soon, the kmem_alloc above will blow up when it causes
- * a call to pmap_enter, and pmap_enter tries to manipulate the
- * (not yet existing) pv_list.
- */
- pmap_phys_start = phys_start;
- pmap_phys_end = phys_end;
-
- pmap_initialized = TRUE;
-
-} /* pmap_init() */
-
-
-/*
- * Routine: PMAP_ZERO_PAGE
- *
- * History:
- * '90.7.13 Fuzzy
- * '90.9.05 Fuzzy
- * Bug: template page invalid --> template page valid
- *
- * template = M88K_TRUNC_PAGE(phys)
- * | m88k_protection (kernel_pmap, VM_PROT_READ | VM_PROT_WRITE)
- * | DT_VALID;
- * ^^^^^^^^ add
- *
- * Function:
- * Zeros the specified (machine independent) page.
- *
- * Parameters:
- * phys PA of page to zero
- *
- * Extern/Global:
- * phys_map_vaddr1
- *
- * Calls:
- * M88K_TRUNC_PAGE
- * m88k_protection
- * cmmu_sflush_page
- * DO_PTES
- * bzero
- *
- * Special Assumptions:
- * no locking required
- *
- * This routine maps the physical pages ath the 'phys_map' virtual
- * address set up in pmap_bootstrap. It flushes the TLB to make the new
- * mappings effective, and zeros all the bits.
- */
-void pmap_zero_page(vm_offset_t phys)
-{
- vm_offset_t srcva;
- pte_template_t template;
- unsigned int i;
- unsigned int spl_sav;
-
- register int my_cpu = cpu_number();
- pt_entry_t *srcpte;
-
- srcva = (vm_offset_t)(phys_map_vaddr1 + (my_cpu * PAGE_SIZE));
- srcpte = pmap_pte(kernel_pmap, srcva);
-
- for (i = 0; i < ptes_per_vm_page; i++, phys += M88K_PGBYTES)
- {
- template.bits = M88K_TRUNC_PAGE(phys)
- | m88k_protection (kernel_pmap, VM_PROT_READ | VM_PROT_WRITE)
- | DT_VALID | CACHE_GLOBAL;
-
-
- spl_sav = splblock();
- cmmu_flush_tlb(1, srcva, M88K_PGBYTES);
- *srcpte = template.pte;
- splx(spl_sav);
- bzero (srcva, M88K_PGBYTES);
- /* force the data out */
- cmmu_flush_remote_data_cache(my_cpu,phys, M88K_PGBYTES);
- }
-
-} /* pmap_zero_page() */
-
-
-/*
- * Routine: PMAP_CREATE
- *
- * Author: Fuzzy
- *
- * History:
- * '90.7.13 Fuzzy level 1 --> segment exchange
- * '90.7.16 Fuzzy PT_ALIGNED --> PAGE_ALIGNED exchange
- * l1_utemplate delete
- * '90.7.20 Fuzzy kernel segment entries in segment table
- * entries for user space address delete.
- * copying kernel segment entries
- * to user pmap segment entries delete.
- * all user segment table entries initialize
- * to zero (invalid).
- *
- * Function:
- * Create and return a physical map. If the size specified for the
- * map is zero, the map is an actual physical map, and may be referenced
- * by the hardware. If the size specified is non-zero, the map will be
- * used in software only, and is bounded by that size.
- *
- * Paramerters:
- * size size of the map
- *
- * Calls:
- * zalloc
- * simple_lock_init
- *
- * This routines allocates a pmap structure and segment translation
- * table from the zones set up by pmap_init. The segment table entries
- * for user space addresses are initalized to zero (invalid).
- * The pmap structure is initalized with the virtual and physical
- * addresses of the segment table. The address (virtual) of the
- * pmap structure is returned.
- */
-pmap_t pmap_create(vm_size_t size)
-{
- register pmap_t p;
-
- /*
- * A software use-only map doesn't even need a map.
- */
- if (size != 0)
- return(PMAP_NULL);
-
- CHECK_PMAP_CONSISTENCY("pmap_create");
-
- p = (pmap_t)malloc(sizeof(*p), M_VMPMAP, M_WAITOK);
- if (p == PMAP_NULL) {
- panic("pmap_create: cannot allocate a pmap");
- }
-
- bzero(p, sizeof(*p));
- pmap_pinit(p);
- return(p);
-
-} /* pmap_create() */
-
-void
-pmap_pinit(pmap_t p)
-{
- register pmap_statistics_t stats;
- sdt_entry_t *segdt;
- int i;
-
- /*
- * Allocate memory for *actual* segment table and *shadow* table.
- */
- segdt = kmem_alloc(kernel_map, 2 * SDT_SIZE);
- if (segdt == NULL)
- panic("pmap_create: kmem_alloc failure");
-
-#if 0
- /* maybe, we can use bzero to zero out the segdt. */
- bzero(segdt, 2 * SDT_SIZE); */
-#endif /* 0 */
- /* use pmap zero page to zero it out */
- pmap_zero_page(pmap_extract(kernel_pmap,(vm_offset_t)segdt));
- if (PAGE_SIZE == SDT_SIZE) /* only got half */
- pmap_zero_page(pmap_extract(kernel_pmap,(vm_offset_t)segdt+PAGE_SIZE));
- if (PAGE_SIZE < 2*SDT_SIZE) /* get remainder */
- bzero((vm_offset_t)segdt+PAGE_SIZE, (2*SDT_SIZE)-PAGE_SIZE);
-
- /*
- * Initialize pointer to segment table both virtual and physical.
- */
- p->sdt_vaddr = segdt;
- p->sdt_paddr = (sdt_entry_t *)pmap_extract(kernel_pmap,(vm_offset_t)segdt);
-
- if (!PAGE_ALIGNED(p->sdt_paddr)) {
- printf("pmap_create: std table = %x\n",(int)p->sdt_paddr);
- panic("pmap_create: sdt_table not aligned on page boundary");
- }
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_CREAT | CD_NORM)) == (CD_CREAT | CD_NORM)) {
- printf("(pmap_create :%x) pmap=0x%x, sdt_vaddr=0x%x, sdt_paddr=0x%x\n",
- curproc, (unsigned)p, p->sdt_vaddr, p->sdt_paddr);
- }
-#endif
-
- /*
- * memory for page tables should be CACHE DISABLED
- */
- pmap_cache_ctrl(kernel_pmap,
- (vm_offset_t)segdt,
- (vm_offset_t)segdt+SDT_SIZE,
- CACHE_INH);
- /*
- * Initalize SDT_ENTRIES.
- */
- /*
- * There is no need to clear segment table, since kmem_alloc would
- * provides us clean pages.
- */
-
- /*
- * Initialize pmap structure.
- */
- p->ref_count = 1;
-
-#ifdef OMRON_PMAP
- /* initialize block address translation cache */
- for (i = 0; i < BATC_MAX; i++) {
- p->i_batc[i].bits = 0;
- p->d_batc[i].bits = 0;
- }
-#endif
-
- /*
- * Initialize statistics.
- */
- stats = &p->stats;
- stats->resident_count = 0;
- stats->wired_count = 0;
-
-#ifdef DEBUG
- /* link into list of pmaps, just after kernel pmap */
- p->next = kernel_pmap->next;
- p->prev = kernel_pmap;
- kernel_pmap->next = p;
- p->next->prev = p;
-#endif
-
-} /* pmap_pinit() */
-
-/*
- * Routine: PMAP_FREE_TABLES (internal)
- *
- * History:
- * '90. 7.16 Fuzzy level 3 --> page discriptor table
- * level 1 --> segment discriptor table
- * 90/07/20 N.Sugai sdt_zone no longer exist. We must
- * use kmem_free instead of zfree.
- * '90. 7.26 Fuzzy VM_MIN_ADDRESS -> VM_MIN_USER_ADDRESS
- * VM_MIN_KERNEL_ADDRESS -> VM_MAX_USER_ADDRESS
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.22 Fuzzy Debugging message add
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- * '90. 9.11 Fuzzy sdt_va: vm_offset_t --> unsigned long
- *
- * Internal procedure used by pmap_destroy() to actualy deallocate
- * the tables.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Calls:
- * pmap_pte
- * kmem_free
- * PT_FREE
- *
- * Special Assumptions:
- * No locking is needed, since this is only called which the
- * ref_count field of the pmap structure goes to zero.
- *
- * This routine sequences of through the user address space, releasing
- * all translation table space back to the system using PT_FREE.
- * The loops are indexed by the virtual address space
- * ranges represented by the table group sizes(PDT_TABLE_GROUP_VA_SPACE).
- *
- */
-
-static void pmap_free_tables(pmap_t pmap)
-{
- unsigned long sdt_va; /* outer loop index */
- sdt_entry_t *sdttbl; /* ptr to first entry in the segment table */
- pt_entry_t *gdttbl; /* ptr to first entry in a page table */
- unsigned int i,j;
-
-#if DEBUG
- if ((pmap_con_dbg & (CD_FREE | CD_NORM)) == (CD_FREE | CD_NORM))
- printf("(pmap_free_tables :%x) pmap %x\n", curproc, pmap);
-#endif
-
- sdttbl = pmap->sdt_vaddr; /* addr of segment table */
-
- /*
- This contortion is here instead of the natural loop
- because of integer overflow/wraparound if VM_MAX_USER_ADDRESS is near 0xffffffff
- */
-
- i = VM_MIN_USER_ADDRESS / PDT_TABLE_GROUP_VA_SPACE;
- j = VM_MAX_USER_ADDRESS / PDT_TABLE_GROUP_VA_SPACE;
- if ( j < 1024 ) j++;
-
- /* Segment table Loop */
- for ( ; i < j; i++)
- {
- sdt_va = PDT_TABLE_GROUP_VA_SPACE*i;
- if ((gdttbl = pmap_pte(pmap, (vm_offset_t)sdt_va)) != PT_ENTRY_NULL) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_FREE | CD_FULL)) == (CD_FREE | CD_FULL))
- printf("(pmap_free_tables :%x) free page table = 0x%x\n", curproc, gdttbl);
-#endif
- PT_FREE(gdttbl);
- }
-
- } /* Segment Loop */
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_FREE | CD_FULL)) == (CD_FREE | CD_FULL))
- printf("(pmap_free_tables :%x) free segment table = 0x%x\n", curproc, sdttbl);
-#endif
- /*
- * Freeing both *actual* and *shadow* segment tables
- */
- kmem_free(kernel_map, (vm_offset_t)sdttbl, 2*SDT_SIZE);
-
-} /* pmap_free_tables() */
-
-
-void
-pmap_release(register pmap_t p)
-{
- pmap_free_tables(p);
-#ifdef DBG
- DEBUG ((pmap_con_dbg & (CD_DESTR | CD_NORM)) == (CD_DESTR | CD_NORM))
- printf("(pmap_destroy :%x) ref_count = 0\n", curproc);
- /* unlink from list of pmap structs */
- p->prev->next = p->next;
- p->next->prev = p->prev;
-#endif
-
-}
-
-/*
- * Routine: PMAP_DESTROY
- *
- * History:
- * '90. 7.16 Fuzzy
- *
- * Function:
- * Retire the given physical map from service. Should only be called
- * if the map contains no valid mappings.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Calls:
- * CHECK_PMAP_CONSISTENCY
- * PMAP_LOCK, PMAP_UNLOCK
- * pmap_free_tables
- * zfree
- *
- * Special Assumptions:
- * Map contains no valid mappings.
- *
- * This routine decrements the reference count in the pmap
- * structure. If it goes to zero, pmap_free_tables is called to release
- * the memory space to the system. Then, call kmem_free to free the
- * pmap structure.
- */
-void pmap_destroy(register pmap_t p)
-{
- register int c, s;
-
- if (p == PMAP_NULL) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_DESTR | CD_NORM)) == (CD_DESTR | CD_NORM))
- printf("(pmap_destroy :%x) pmap is NULL\n", curproc);
-#endif
- return;
- }
-
- if (p == kernel_pmap) {
- panic("pmap_destroy: Attempt to destroy kernel pmap");
- }
-
- CHECK_PMAP_CONSISTENCY("pmap_destroy");
-
- PMAP_LOCK(p, s);
- c = --p->ref_count;
- PMAP_UNLOCK(p, s);
-
- if (c == 0) {
- pmap_release(p);
- free((caddr_t)p,M_VMPMAP);
- }
-
-} /* pmap_destroy() */
-
-
-/*
- * Routine: PMAP_REFERENCE
- *
- * Author: Fuzzy
- *
- * Function:
- * Add a reference to the specified pmap.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Calls:
- * PMAP_LOCK, PMAP_UNLOCK
- *
- * Under a pmap read lock, the ref_count field of the pmap structure
- * is incremented. The function then returns.
- */
-void pmap_reference(register pmap_t p)
-{
- int s;
-
- if (p != PMAP_NULL) {
- PMAP_LOCK(p, s);
- p->ref_count++;
- PMAP_UNLOCK(p, s);
- }
-
-} /* pmap_reference */
-
-
-/*
- * Routine: PMAP_REMOVE_RANGE (internal)
- *
- * Update:
- *
- * July 16, 90 - JUemura initial porting
- * '90.7.27 Fuzzy Calls: add Macros
- * '90.8.3 Fuzzy if defined TEST, 'static' undeclared.
- * '90.8.29 Fuzzy line 112 (if (pte == PT_ENTRY_NULL) { ...)
- * delete (check sdt invalid).
- * '90.8.30 Fuzzy delete "if defined TEST, 'static' undeclared."
- *
- * Function:
- * Invalidate page table entries associated with the
- * given virtual address range. The entries given are the first
- * (inclusive) and last (exclusive) entries for the VM pages.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * s virtual address of start of range to remove
- * e virtual address of start of range to remove
- *
- * External/Global:
- * pv lists
- * pmap_modify_list
- *
- * Calls:
- * CHECK_PAGE_ALIGN
- * SDTENT
- * SDT_VALID
- * SDT_NEXT
- * pmap_pte
- * PDT_VALID
- * M88K_PTOB
- * PMAP_MANAGED
- * PFIDX
- * LOCK_PVH
- * UNLOCK_PVH
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * zfree
- * invalidate_pte
- * flush_atc_entry
- * vm_page_set_modified
- * PHYS_TO_VM_PAGE
- *
- * Special Assumptions:
- * The pmap must be locked.
- *
- * This routine sequences through the pages defined by the given
- * range. For each page, pmap_pte is called to obtain a (virtual)
- * pointer to the page table entry (PTE) associated with the page's
- * virtual address. If the page table entry does not exist, or is invalid,
- * nothing need be done.
- *
- * If the PTE is valid, the routine must invalidated the entry. The
- * 'modified' bit, if on, is referenced to the VM through the
- * 'vm_page_set_modified' macro, and into the appropriate entry in the
- * pmap_modify_list. Next, the function must find the PV list entry
- * associated with this pmap/va (if it doesn't exist - the function
- * panics). The PV list entry is unlinked from the list, and returned to
- * its zone.
- */
-
-static void pmap_remove_range(pmap_t pmap, vm_offset_t s, vm_offset_t e)
-{
- int pfi;
- int pfn;
- int num_removed = 0,
- num_unwired = 0;
- register int i;
- pt_entry_t *pte;
- pv_entry_t prev, cur;
- pv_entry_t pvl;
- vm_offset_t pa, va, tva;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (e <= s)
- panic("pmap_remove_range: end < start");
-
- /*
- * Pmap has been locked by pmap_remove.
- */
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- /*
- * Loop through the range in vm_page_size increments.
- * Do not assume that either start or end fail on any
- * kind of page boundary (though this may be true!?).
- */
-
- CHECK_PAGE_ALIGN(s, "pmap_remove_range - start addr");
-
- for (va = s; va < e; va += PAGE_SIZE) {
-
- sdt_entry_t *sdt;
-
- sdt = SDTENT(pmap,va);
-
- if (!SDT_VALID(sdt)) {
- va &= SDT_MASK; /* align to segment */
- if (va <= e - (1<<SDT_SHIFT))
- va += (1<<SDT_SHIFT) - PAGE_SIZE; /* no page table, skip to next seg entry */
- else /* wrap around */
- break;
- continue;
- }
-
- pte = pmap_pte(pmap,va);
-
- if (!PDT_VALID(pte)) {
- continue; /* no page mapping */
- }
-
- num_removed++;
-
- if (pte->wired)
- num_unwired++;
-
- pfn = pte->pfn;
- pa = M88K_PTOB(pfn);
-
- if (PMAP_MANAGED(pa)) {
- pfi = PFIDX(pa);
- /*
- * Remove the mapping from the pvlist for
- * this physical page.
- */
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST(pa, pvl, "pmap_remove_range before");
-
- if (pvl->pmap == PMAP_NULL)
- panic("pmap_remove: null pv_list");
-
- if (pvl->va == va && pvl->pmap == pmap) {
-
- /*
- * Hander is the pv_entry. Copy the next one
- * to hander and free the next one (we can't
- * free the hander)
- */
- cur = pvl->next;
- if (cur != PV_ENTRY_NULL) {
- *pvl = *cur;
- free((caddr_t)cur, M_VMPVENT);
- } else {
- pvl->pmap = PMAP_NULL;
- }
-
- } else {
-
- for (prev = pvl; (cur = prev->next) != PV_ENTRY_NULL; prev = cur) {
- if (cur->va == va && cur->pmap == pmap) {
- break;
- }
- }
- if (cur == PV_ENTRY_NULL) {
- printf("pmap_remove_range: looking for VA "
- "0x%x PV list at 0x%x\n", va, (unsigned)pvl);
- panic("pmap_remove_range: mapping not in pv_list");
- }
-
- prev->next = cur->next;
- free((caddr_t)cur, M_VMPVENT);
- }
-
- CHECK_PV_LIST(pa, pvl, "pmap_remove_range after");
-
- } /* if PAGE_MANAGED */
-
- /*
- * For each pte in vm_page (NOTE: vm_page, not
- * M88K (machine dependent) page !! ), reflect
- * modify bits to pager and zero (invalidate,
- * remove) the pte entry.
- */
- tva = va;
- for (i = ptes_per_vm_page; i > 0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- opte.bits = invalidate_pte(pte);
- flush_atc_entry(0, tva, kflush);
-
- if (opte.pte.modified) {
- vm_page_set_modified(PHYS_TO_VM_PAGE(opte.bits & M88K_PGMASK));
- /* keep track ourselves too */
- if (PMAP_MANAGED(pa))
- pmap_modify_list[pfi] = 1;
- }
- pte++;
- tva += M88K_PGBYTES;
- }
-
- } /* end for ( va = s; ...) */
-
- /*
- * Update the counts
- */
- pmap->stats.resident_count -= num_removed;
- pmap->stats.wired_count -= num_unwired;
-
-} /* pmap_remove_range */
-
-/*
- * Routine: PMAP_REMOVE
- *
- * History:
- * '90.7.16 Fuzzy Unchanged
- * '90.7.26 Fuzzy VM_MIN_KERNEL_ADDRESS -> VM_MAX_USER_ADDRESS
- * '90.8.23 Fuzzy add Debugging message
- *
- * Function:
- * Remove the given range of addresses from the specified map.
- * It is assumed that start is properly rounded to the VM page size.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Special Assumptions:
- * Assumes not all entries must be valid in specified range.
- *
- * Calls:
- * CHECK_PAGE_ALIGN
- * PMAP_LOCK, PMAP_UNLOCK
- * pmap_remove_range
- * panic
- *
- * After taking pmap read lock, pmap_remove_range is called to do the
- * real work.
- */
-void
-pmap_remove(pmap_t map, vm_offset_t s, vm_offset_t e)
-{
- int spl;
-
- if (map == PMAP_NULL) {
- return;
- }
-
-#if DEBUG
- if ((pmap_con_dbg & (CD_RM | CD_NORM)) == (CD_RM | CD_NORM))
- printf("(pmap_remove :%x) map %x s %x e %x\n", curproc, map, s, e);
-#endif
-
- CHECK_PAGE_ALIGN(s, "pmap_remove start addr");
-
- if (s>e)
- panic("pmap_remove: start greater than end address");
-
- pmap_remove_range(map, s, e);
-} /* pmap_remove() */
-
-
-/*
- * Routine: PMAP_REMOVE_ALL
- *
- * History:
- * '90.7.27 Fuzzy 'Calls:' modify
- * '90.8.28 Fuzzy add Debugging message
- *
- * Function:
- * Removes this physical page from all physical maps in which it
- * resides. Reflects back modify bits to the pager.
- *
- * Parameters:
- * phys physical address of pages which is to
- * be removed from all maps
- *
- * Extern/Global:
- * pv_head_array, pv lists
- * pmap_modify_list
- *
- * Calls:
- * PMAP_MANAGED
- * SPLVM, SPLX
- * PFIDX
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * simple_lock
- * M88K_PTOB
- * PDT_VALID
- * pmap_pte
- * vm_page_set_modified
- * PHYS_TO_VM_PAGE
- * zfree
- *
- * If the page specified by the given address is not a managed page,
- * this routine simply returns. Otherwise, the PV list associated with
- * that page is traversed. For each pmap/va pair pmap_pte is called to
- * obtain a pointer to the page table entry (PTE) associated with the
- * va (the PTE must exist and be valid, otherwise the routine panics).
- * The hardware 'modified' bit in the PTE is examined. If it is on, the
- * pmap_modify_list entry corresponding to the physical page is set to 1.
- * Then, the PTE is invalidated, and the PV list entry is unlinked and
- * freed.
- *
- * At the end of this function, the PV list for the specified page
- * will be null.
- */
-void
-pmap_remove_all(vm_offset_t phys)
-{
- pv_entry_t pvl, cur;
- register pt_entry_t *pte;
- int pfi;
- register int i;
- register vm_offset_t va;
- register pmap_t pmap;
- int spl;
- int dbgcnt = 0;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (!PMAP_MANAGED(phys)) {
- /* not a managed page. */
-#ifdef DEBUG
- if (pmap_con_dbg & CD_RMAL)
- printf("(pmap_remove_all :%x) phys addr 0x%x not a managed page\n", curproc, phys);
-#endif
- return;
- }
-
- SPLVM(spl);
-
- /*
- * Walk down PV list, removing all mappings.
- * We have to do the same work as in pmap_remove_pte_page
- * since that routine locks the pv_head. We don't have
- * to lock the pv_head, since we have the entire pmap system.
- */
-remove_all_Retry:
-
- pfi = PFIDX(phys);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST(phys, pvl, "pmap_remove_all before");
-
- /*
- * Loop for each entry on the pv list
- */
- while ((pmap = pvl->pmap) != PMAP_NULL) {
- va = pvl->va;
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- pte = pmap_pte(pmap, va);
-
- /*
- * Do a few consistency checks to make sure
- * the PV list and the pmap are in synch.
- */
- if (pte == PT_ENTRY_NULL) {
- printf("(pmap_remove_all :%x) phys %x pmap %x va %x dbgcnt %x\n",
- (unsigned)curproc, phys, (unsigned)pmap, va, dbgcnt);
- panic("pmap_remove_all: pte NULL");
- }
- if (!PDT_VALID(pte))
- panic("pmap_remove_all: pte invalid");
- if (M88K_PTOB(pte->pfn) != phys)
- panic("pmap_remove_all: pte doesn't point to page");
- if (pte->wired)
- panic("pmap_remove_all: removing a wired page");
-
- pmap->stats.resident_count--;
-
- if ((cur = pvl->next) != PV_ENTRY_NULL) {
- *pvl = *cur;
- free((caddr_t)cur, M_VMPVENT);
- }
- else
- pvl->pmap = PMAP_NULL;
-
- /*
- * Reflect modified pages to pager.
- */
- for (i = ptes_per_vm_page; i>0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- opte.bits = invalidate_pte(pte);
- flush_atc_entry(users, va, kflush);
-
- if (opte.pte.modified) {
- vm_page_set_modified((vm_page_t)PHYS_TO_VM_PAGE(phys));
- /* keep track ourselves too */
- pmap_modify_list[pfi] = 1;
- }
- pte++;
- va += M88K_PGBYTES;
- }
-
- /*
- * Do not free any page tables,
- * leaves that for when VM calls pmap_collect().
- */
- dbgcnt++;
- }
- CHECK_PV_LIST(phys, pvl, "pmap_remove_all after");
-
- SPLX(spl);
-
-} /* pmap_remove_all() */
-
-
-
-
-/*
- * Routine: PMAP_COPY_ON_WRITE
- *
- * History:
- * '90. 7.16 Fuzzy level 3 --> page table changed
- * '90. 7.19 Fuzzy Comment 'Calls' add
- * '90. 7.26 Fuzzy VM_MIN_KERNEL_ADDRESS -> VM_MAX_USER_ADDRESS
- * '90. 8.18 Fuzzy Add Debugging Message (PA no mappings)
- * '90. 8.18 Fuzzy Bug Fixs
- * for (i=ptes_per_vm_page; i>0; i++) {
- * ^^
- * for (i=ptes_per_vm_page; i>0; i--) {
- *
- * Function:
- * Remove write privileges from all physical maps for this physical page.
- *
- * Parameters:
- * phys physical address of page to be read-protected.
- *
- * Calls:
- * SPLVM, SPLX
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * simple_lock, simple_unlock
- * panic
- * PDT_VALID
- * M88K_PTOB
- * pmap_pte
- *
- * Special Assumptions:
- * All mapings of the page are user-space mappings.
- *
- * This routine walks the PV list. For each pmap/va pair it locates
- * the page table entry (the PTE), and sets the hardware enforced
- * read-only bit. The TLB is appropriately flushed.
- */
-static void pmap_copy_on_write(vm_offset_t phys)
-{
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
- register int i;
- int spl, spl_sav;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (!PMAP_MANAGED(phys)) {
-#ifdef DEBUG
- if (pmap_con_dbg & CD_CMOD)
- printf("(pmap_copy_on_write :%x) phys addr 0x%x not managed \n", curproc, phys);
-#endif
- return;
- }
-
- SPLVM(spl);
-
- pv_e = PFIDX_TO_PVH(PFIDX(phys));
- CHECK_PV_LIST(phys, pv_e, "pmap_copy_on_write before");
- if (pv_e->pmap == PMAP_NULL) {
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_COW | CD_NORM)) == (CD_COW | CD_NORM))
- printf("(pmap_copy_on_write :%x) phys addr 0x%x not mapped\n", curproc, phys);
-#endif
-
- SPLX(spl);
-
- return; /* no mappings */
- }
-
- /*
- * Run down the list of mappings to this physical page,
- * disabling write privileges on each one.
- */
-
- while (pv_e != PV_ENTRY_NULL) {
- pmap_t pmap;
- vm_offset_t va;
-
- pmap = pv_e->pmap;
- va = pv_e->va;
-
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- /*
- * Check for existing and valid pte
- */
- pte = pmap_pte(pmap, va);
- if (pte == PT_ENTRY_NULL)
- panic("pmap_copy_on_write: pte from pv_list not in map");
- if (!PDT_VALID(pte))
- panic("pmap_copy_on_write: invalid pte");
- if (M88K_PTOB(pte->pfn) != phys)
- panic("pmap_copy_on_write: pte doesn't point to page");
-
- /*
- * Flush TLBs of which cpus using pmap.
- */
-
- for (i = ptes_per_vm_page; i > 0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- opte.pte.prot = M88K_RO;
- ((pte_template_t *)pte)->bits = opte.bits;
- flush_atc_entry(users, va, kflush);
- splx(spl_sav);
- pte++;
- va += M88K_PGBYTES;
- }
-
- pv_e = pv_e->next;
- }
- CHECK_PV_LIST(phys, PFIDX_TO_PVH(PFIDX(phys)), "pmap_copy_on_write");
-
- SPLX(spl);
-
-} /* pmap_copy_on_write */
-
-
-
-/*
- * Routine: PMAP_PROTECT
- *
- * History:
- * '90.7.16 Fuzzy
- * '90.7.26 Fuzzy VM_MIN_KERNEL_ADDRESS -> VM_MAX_USER_ADDRESS
- * '90.8.21 Fuzzy Debugging message add
- *
- * Function:
- * Sets the physical protection on the specified range of this map
- * as requested.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * s start address of start of range
- * e end address of end of range
- * prot desired protection attributes
- *
- * Calls:
- * m88k_protection
- * PMAP_LOCK, PMAP_UNLOCK
- * CHECK_PAGE_ALIGN
- * panic
- * pmap_pte
- * SDT_NEXT
- * PDT_VALID
- *
- * This routine sequences through the pages of the specified range.
- * For each, it calls pmap_pte to acquire a pointer to the page table
- * entry (PTE). If the PTE is invalid, or non-existant, nothing is done.
- * Otherwise, the PTE's protection attributes are adjusted as specified.
- */
-void pmap_protect(
- pmap_t pmap,
- vm_offset_t s,
- vm_offset_t e,
- vm_prot_t prot)
-{
- pte_template_t maprot;
- unsigned ap;
- int spl, spl_sav;
- register int i;
- pt_entry_t *pte;
- vm_offset_t va, tva;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (pmap == PMAP_NULL || prot & VM_PROT_WRITE)
- return;
- if ((prot & VM_PROT_READ) == 0) {
- pmap_remove(pmap, s, e);
- return;
- }
- if (s > e)
- panic("pmap_protect: start grater than end address");
-
- maprot.bits = m88k_protection(pmap, prot);
- ap = maprot.pte.prot;
-
- PMAP_LOCK(pmap, spl);
-
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- CHECK_PAGE_ALIGN(s, "pmap_protect");
-
- /*
- * Loop through the range in vm_page_size increment.
- * Do not assume that either start or end fall on any
- * kind of page boundary (though this may be true ?!).
- */
- for (va = s; va <= e; va += PAGE_SIZE) {
-
- pte = pmap_pte(pmap, va);
-
- if (pte == PT_ENTRY_NULL) {
-
- va &= SDT_MASK; /* align to segment */
- if (va <= e - (1<<SDT_SHIFT))
- va += (1<<SDT_SHIFT) - PAGE_SIZE; /* no page table, skip to next seg entry */
- else /* wrap around */
- break;
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_PROT | CD_FULL)) == (CD_PROT | CD_FULL))
- printf("(pmap_protect :%x) no page table :: skip to 0x%x\n", curproc, va + PAGE_SIZE);
-#endif
- continue;
- }
-
- if (!PDT_VALID(pte)) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_PROT | CD_FULL)) == (CD_PROT | CD_FULL))
- printf("(pmap_protect :%x) pte invalid pte @ 0x%x\n", curproc, pte);
-#endif
- continue; /* no page mapping */
- }
-
- tva = va;
- for (i = ptes_per_vm_page; i>0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- opte.pte.prot = ap;
- ((pte_template_t *)pte)->bits = opte.bits;
- flush_atc_entry(0, tva, kflush);
- splx(spl_sav);
- pte++;
- tva += M88K_PGBYTES;
- }
- }
-
- PMAP_UNLOCK(pmap, spl);
-
-} /* pmap_protect() */
-
-
-
-/*
- * Routine: PMAP_EXPAND
- *
- * History:
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.16 Fuzzy
- * Extern/Global no --> user_pt_map, kernel_pmap
- * added Debug message
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- * Function:
- * Expands a pmap to be able to map the specified virtual address.
- * New kernel virtual memory is allocated for a page table
- *
- * Must be called with the pmap system and the pmap unlocked, since
- * these must be unlocked to use vm_allocate or vm_deallocate (via
- * kmem_alloc, zalloc). Thus it must be called in a unlock/lock loop
- * that checks whether the map has been expanded enough. ( We won't loop
- * forever, since page table aren't shrunk.)
- *
- * Parameters:
- * map point to map structure
- * v VA indicating which tables are needed
- *
- * Extern/Global:
- * user_pt_map
- * kernel_pmap
- *
- * Calls:
- * pmap_pte
- * kmem_alloc
- * kmem_free
- * zalloc
- * zfree
- * pmap_extract
- *
- * Special Assumptions
- * no pmap locks held
- *
- * 1: This routine immediately allocates space for a page table.
- *
- * 2: The page table entries (PTEs) are initialized (set invalid), and
- * the corresponding segment table entry is set to point to the new
- * page table.
- *
- *
- * if (kernel_pmap)
- * pmap_expand_kmap()
- * ptva = kmem_alloc(user_pt_map)
- *
- */
-static void pmap_expand(pmap_t map, vm_offset_t v)
-{
- int i,
- spl;
- vm_offset_t pdt_vaddr,
- pdt_paddr;
-
- sdt_entry_t *sdt;
- pt_entry_t *pte;
- vm_offset_t pmap_extract();
-
- if (map == PMAP_NULL) {
- panic("pmap_expand: pmap is NULL");
- }
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_EXP | CD_NORM)) == (CD_EXP | CD_NORM))
- printf ("(pmap_expand :%x) map %x v %x\n", curproc, map, v);
-#endif
-
- CHECK_PAGE_ALIGN (v, "pmap_expand");
-
- /*
- * Handle kernel pmap in pmap_expand_kmap().
- */
- if (map == kernel_pmap) {
- PMAP_LOCK(map, spl);
- if (pmap_expand_kmap(v, VM_PROT_READ|VM_PROT_WRITE) == PT_ENTRY_NULL)
- panic ("pmap_expand: Cannot allocate kernel pte table");
- PMAP_UNLOCK(map, spl);
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_EXP | CD_FULL)) == (CD_EXP | CD_FULL))
- printf("(pmap_expand :%x) kernel_pmap\n", curproc);
-#endif
- return;
- }
-
- /* XXX */
-#ifdef MACH_KERNEL
- if (kmem_alloc_wired(kernel_map, &pdt_vaddr, PAGE_SIZE) != KERN_SUCCESS)
- panic("pmap_enter: kmem_alloc failure");
- pmap_zero_page(pmap_extract(kernel_pmap, pdt_vaddr));
-#else
- pdt_vaddr = kmem_alloc (kernel_map, PAGE_SIZE);
-#endif
-
- pdt_paddr = pmap_extract(kernel_pmap, pdt_vaddr);
-
- /*
- * the page for page tables should be CACHE DISABLED
- */
- pmap_cache_ctrl(kernel_pmap, pdt_vaddr, pdt_vaddr+PAGE_SIZE, CACHE_INH);
-
- PMAP_LOCK(map, spl);
-
- if ((pte = pmap_pte(map, v)) != PT_ENTRY_NULL) {
- /*
- * Someone else caused us to expand
- * during our vm_allocate.
- */
- PMAP_UNLOCK(map, spl);
- /* XXX */
- kmem_free (kernel_map, pdt_vaddr, PAGE_SIZE);
-#ifdef DEBUG
- if (pmap_con_dbg & CD_EXP)
- printf("(pmap_expand :%x) table has already allocated\n", curproc);
-#endif
- return;
- }
-
- /*
- * Apply a mask to V to obtain the vaddr of the beginning of
- * its containing page 'table group',i.e. the group of
- * page tables that fit eithin a single VM page.
- * Using that, obtain the segment table pointer that references the
- * first page table in the group, and initilize all the
- * segment table descriptions for the page 'table group'.
- */
- v &= ~((1<<(LOG2_PDT_TABLE_GROUP_SIZE+PDT_BITS+PG_BITS))-1);
-
- sdt = SDTENT(map,v);
-
- /*
- * Init each of the segment entries to point the freshly allocated
- * page tables.
- */
-
- for (i = PDT_TABLE_GROUP_SIZE; i>0; i--) {
- ((sdt_entry_template_t *)sdt)->bits = pdt_paddr | M88K_RW | DT_VALID;
- ((sdt_entry_template_t *)(sdt + SDT_ENTRIES))->bits = pdt_vaddr | M88K_RW | DT_VALID;
- sdt++;
- pdt_paddr += PDT_SIZE;
- pdt_vaddr += PDT_SIZE;
- }
-
- PMAP_UNLOCK(map, spl);
-
-} /* pmap_expand() */
-
-
-
-/*
- * Routine: PMAP_ENTER
- *
- *
- * Update:
- * July 13,90 - JUemura
- * initial porting
- * *****TO CHECK*****
- * locks removed since we don't have to allocate
- * level 2 tables anymore. locks needed?
- * '90.7.26 Fuzzy VM_MIN_KERNEL_ADDRESS -> VM_MAX_USER_ADDRESS
- * '90.8.17 Fuzzy Debug message added(PV no mapped at VA)
- * '90.8.31 Sugai Remove redundant message output
- *
- * Function:
- * Insert the given physical page (p) at the specified virtual
- * address (v) in the target phisical map with the protecton requested.
- * If specified, the page will be wired down, meaning that the
- * related pte can not be reclaimed.
- *
- * N.B.: This is only routine which MAY NOT lazy-evaluation or lose
- * information. That is, this routine must actually insert this page
- * into the given map NOW.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * va VA of page to be mapped
- * pa PA of page to be mapped
- * prot protection attributes for page
- * wired wired attribute for page
- *
- * Extern/Global:
- * pv_head_array, pv lists
- * pmap_modify_list
- *
- * Calls:
- * m88k_protection
- * pmap_pte
- * pmap_expand
- * pmap_remove_range
- * zfree
- *
- * This routine starts off by calling pmap_pte to obtain a (virtual)
- * pointer to the page table entry corresponding to given virtual
- * address. If the page table itself does not exist, pmap_expand is
- * called to allocate it.
- *
- * If the page table entry (PTE) already maps the given physical page,
- * all that is needed is to set the protection and wired attributes as
- * given. TLB entries are flushed and pmap_enter returns.
- *
- * If the page table entry (PTE) maps a different physical page than
- * that given, the old mapping is removed by a call to map_remove_range.
- * And execution of pmap_enter continues.
- *
- * To map the new physical page, the routine first inserts a new
- * entry in the PV list exhibiting the given pmap and virtual address.
- * It then inserts the physical page address, protection attributes, and
- * wired attributes into the page table entry (PTE).
- *
- *
- * get machine-dependent prot code
- * get the pte for this page
- * if necessary pmap expand(pmap,v)
- * if (changing wired attribute or protection) {
- * flush entry from TLB
- * update template
- * for (ptes per vm page)
- * stuff pte
- * } else if (mapped at wrong addr)
- * flush entry from TLB
- * pmap_remove_range
- * } else {
- * enter mapping in pv_list
- * setup template and stuff ptes
- * }
- *
- */
-void pmap_enter(
- register pmap_t pmap,
- vm_offset_t va,
- vm_offset_t pa,
- vm_prot_t prot,
- boolean_t wired)
-{
- int ap;
- int spl, spl_sav;
- pv_entry_t pv_e;
- pt_entry_t *pte;
- vm_offset_t old_pa;
- pte_template_t template;
- register int i;
- int pfi;
- pv_entry_t pvl;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (pmap == PMAP_NULL) {
- panic("pmap_enter: pmap is NULL");
- }
-
- CHECK_PAGE_ALIGN (va, "pmap_entry - VA");
- CHECK_PAGE_ALIGN (pa, "pmap_entry - PA");
-
- /*
- * Range check no longer use, since we use whole address space
- */
-
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_ENT | CD_NORM)) == (CD_ENT | CD_NORM)) {
- if (pmap == kernel_pmap)
- printf ("(pmap_enter :%x) pmap kernel va %x pa %x\n", curproc, va, pa);
- else
- printf ("(pmap_enter :%x) pmap %x va %x pa %x\n", curproc, pmap, va, pa);
- }
-#endif
-
- ap = m88k_protection (pmap, prot);
-
- /*
- * Must allocate a new pvlist entry while we're unlocked;
- * zalloc may cause pageout (which will lock the pmap system).
- * If we determine we need a pvlist entry, we will unlock
- * and allocate one. Then will retry, throwing away
- * the allocated entry later (if we no longer need it).
- */
- pv_e = PV_ENTRY_NULL;
- Retry:
-
- PMAP_LOCK(pmap, spl);
-
- /*
- * Expand pmap to include this pte. Assume that
- * pmap is always expanded to include enough M88K
- * pages to map one VM page.
- */
- while ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL) {
- /*
- * Must unlock to expand the pmap.
- */
- PMAP_UNLOCK(pmap, spl);
- pmap_expand(pmap, va);
- PMAP_LOCK(pmap, spl);
- }
-
- /*
- * Special case if the physical page is already mapped
- * at this address.
- */
- old_pa = M88K_PTOB(pte->pfn);
- if (old_pa == pa) {
-
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- /*
- * May be changing its wired attributes or protection
- */
-
- if (wired && !pte->wired)
- pmap->stats.wired_count++;
- else if (!wired && pte->wired)
- pmap->stats.wired_count--;
-
-/*#ifdef luna88k*/ /* KLUDGE (or is it?) */ /* is it for dealing with IO mem? */
- if (pa >= MAXPHYSMEM)
- template.bits = DT_VALID | ap | M88K_TRUNC_PAGE(pa) | CACHE_INH;
- else
-/*#endif*/
- template.bits = DT_VALID | ap | M88K_TRUNC_PAGE(pa) | CACHE_GLOBAL /*XXX*/;
- if (wired)
- template.pte.wired = 1;
-
- /*
- * If there is a same mapping, we have nothing to do.
- */
- if ( !PDT_VALID(pte) || (pte->wired != template.pte.wired)
- || (pte->prot != template.pte.prot)) {
-
- for (i = ptes_per_vm_page; i>0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- template.pte.modified = opte.pte.modified;
- *pte++ = template.pte;
- flush_atc_entry(users, va, kflush);
- splx(spl_sav);
- template.bits += M88K_PGBYTES;
- va += M88K_PGBYTES;
- }
- }
-
- } else { /* if ( pa == old_pa) */
-
- /*
- * Remove old mapping from the PV list if necessary.
- */
- if (old_pa != (vm_offset_t) 0) {
- /*
- * Invalidate the translation buffer,
- * then remove the mapping.
- */
- pmap_remove_range(pmap, va, va + PAGE_SIZE);
- }
-
- if (PMAP_MANAGED(pa)) {
-
- /*
- * Enter the mappimg in the PV list for this
- * physical page.
- */
- pfi = PFIDX(pa);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST (pa, pvl, "pmap_enter before");
-
- if (pvl->pmap == PMAP_NULL) {
-
- /*
- * No mappings yet
- */
- pvl->va = va;
- pvl->pmap = pmap;
- pvl->next = PV_ENTRY_NULL;
-
- } else {
-#ifdef DEBUG
- /*
- * check that this mapping is not already there
- */
- {
- pv_entry_t e = pvl;
- while (e != PV_ENTRY_NULL) {
- if (e->pmap == pmap && e->va == va)
- panic ("pmap_enter: already in pv_list");
- e = e->next;
- }
- }
-#endif
- /*
- * Add new pv_entry after header.
- */
- if (pv_e == PV_ENTRY_NULL) {
- PMAP_UNLOCK(pmap, spl);
- pv_e = (pv_entry_t) malloc(sizeof *pv_e, M_VMPVENT,
- M_NOWAIT);
- goto Retry;
- }
- pv_e->va = va;
- pv_e->pmap = pmap;
- pv_e->next = pvl->next;
- pvl->next = pv_e;
- /*
- * Remeber that we used the pvlist entry.
- */
- pv_e = PV_ENTRY_NULL;
- }
- }
-
- /*
- * And count the mapping.
- */
- pmap->stats.resident_count++;
- if (wired)
- pmap->stats.wired_count++;
-
-/*#ifdef luna88k */ /* KLUDGE (or is it?) */
- if (pa >= MAXPHYSMEM)
- template.bits = DT_VALID | ap | M88K_TRUNC_PAGE(pa) | CACHE_INH;
- else
- /* SHOULDN't THE NEXT THING HAVE CACHE_GLOBAL? */
-/*#endif */
- template.bits = DT_VALID | ap | M88K_TRUNC_PAGE(pa);
-
- if (wired)
- template.pte.wired = 1;
-
- DO_PTES (pte, template.bits);
-
- } /* if ( pa == old_pa ) ... else */
-
- PMAP_UNLOCK(pmap, spl);
-
- if (pv_e != PV_ENTRY_NULL)
- free((caddr_t) pv_e, M_VMPVENT);
-
-} /* pmap_enter */
-
-
-
-/*
- * Routine: pmap_change_wiring
- *
- * Author: Fuzzy
- *
- * Function: Change the wiring attributes for a map/virtual-address
- * Pair.
- * Prameterts:
- * pmap pointer to pmap structure
- * v virtual address of page to be wired/unwired
- * wired flag indicating new wired state
- *
- * Extern/Global:
- * pte_per_vm_page
- *
- * Calls:
- * PMAP_LOCK, PMAP_UNLOCK
- * pmap_pte
- * panic
- *
- * Special Assumptions:
- * The mapping must already exist in the pmap.
- */
-void pmap_change_wiring(
- pmap_t map,
- vm_offset_t v,
- boolean_t wired)
-{
- register pt_entry_t *pte;
- register int i;
- int spl;
-
- PMAP_LOCK(map, spl);
-
- if ((pte = pmap_pte(map, v)) == PT_ENTRY_NULL)
- panic ("pmap_change_wiring: pte missing");
-
- if (wired && !pte->wired)
- /*
- * wiring mapping
- */
- map->stats.wired_count++;
-
- else if (!wired && pte->wired)
- /*
- * unwired mapping
- */
- map->stats.wired_count--;
-
- for (i = ptes_per_vm_page; i>0; i--)
- (pte++)->wired = wired;
-
- PMAP_UNLOCK(map, spl);
-
-} /* pmap_change_wiring() */
-
-
-
-/*
- * Routine: PMAP_EXTRACT
- *
- * Author: Fuzzy
- *
- * Function:
- * Extract the physical page address associoated
- * with the given map/virtual_address pair.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * va virtual address
- *
- * Calls:
- * PMAP_LOCK, PMAP_UNLOCK
- * pmap_pte
- *
- *
- * This routine checks BATC mapping first. BATC has been used and
- * the specified pmap is kernel_pmap, batc_entry is scanned to find out
- * the mapping.
- * Then the routine calls pmap_pte to get a (virtual) pointer to
- * the page table entry (PTE) associated with the given virtual
- * address. If the page table does not exist, or if the PTE is not valid,
- * then 0 address is returned. Otherwise, the physical page address from
- * the PTE is returned.
- */
-vm_offset_t pmap_extract(pmap_t pmap, vm_offset_t va)
-{
- register pt_entry_t *pte;
- register vm_offset_t pa;
- register int i;
- int spl;
-
- if (pmap == PMAP_NULL)
- panic("pmap_extract: pmap is NULL");
-
- /*
- * check BATC first
- */
- if (pmap == kernel_pmap && batc_used > 0)
- for (i = batc_used-1; i > 0; i--)
- if (batc_entry[i].lba == M88K_BTOBLK(va)) {
- pa = (batc_entry[i].pba << BATC_BLKSHIFT) | (va & BATC_BLKMASK );
- return(pa);
- }
-
- PMAP_LOCK(pmap, spl);
-
- if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
- pa = (vm_offset_t) 0;
- else {
- if (PDT_VALID(pte))
- pa = M88K_PTOB(pte->pfn);
- else
- pa = (vm_offset_t) 0;
- }
-
- if (pa)
- pa |= (va & M88K_PGOFSET); /* offset within page */
-
- PMAP_UNLOCK(pmap, spl);
-
-#if 0
- printf("pmap_extract ret %x\n", pa);
-#endif /* 0 */
- return(pa);
-
-} /* pamp_extract() */
-
-/*
- a version for the kernel debugger
-*/
-
-vm_offset_t pmap_extract_unlocked(pmap_t pmap, vm_offset_t va)
-{
- register pt_entry_t *pte;
- register vm_offset_t pa;
- register int i;
-
- if (pmap == PMAP_NULL)
- panic("pmap_extract: pmap is NULL");
-
- /*
- * check BATC first
- */
- if (pmap == kernel_pmap && batc_used > 0)
- for (i = batc_used-1; i > 0; i--)
- if (batc_entry[i].lba == M88K_BTOBLK(va)) {
- pa = (batc_entry[i].pba << BATC_BLKSHIFT) | (va & BATC_BLKMASK );
- return(pa);
- }
-
- if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
- pa = (vm_offset_t) 0;
- else {
- if (PDT_VALID(pte))
- pa = M88K_PTOB(pte->pfn);
- else
- pa = (vm_offset_t) 0;
- }
-
- if (pa)
- pa |= (va & M88K_PGOFSET); /* offset within page */
-
- return(pa);
-
-} /* pamp_extract_unlocked() */
-
-
-/*
- * Routine: PMAP_COPY
- *
- * History:
- * '90.7.16 Fuzzy
- *
- * Function:
- * Copy the range specigfied by src_adr/len from the source map
- * to the range dst_addr/len in the destination map. This routine
- * is only advisory and need not do anything.
- *
- * Parameters:
- * dst_pmap pointer to destination pmap structure
- * src_pmap pointer to source pmap structure
- * dst_addr VA in destionation map
- * len length of address space being copied
- * src_addr VA in source map
- *
- * At this time, the 88200 pmap implementation does nothing in this
- * function. Translation tables in the destination map will be allocated
- * at VM fault time.
- */
-void pmap_copy(
- pmap_t dst_pmap,
- pmap_t src_pmap,
- vm_offset_t dst_addr,
- vm_size_t len,
- vm_offset_t src_addr)
-{
-#ifdef lint
- dst_pmap++; src_pmap++; dst_addr++; len++; src_addr++;
-#endif
-
-
-}/* pmap_copy() */
-
-
-/*
- * Routine: PMAP_UPDATE
- *
- * History:
- * '90.7.16 Fuzzy
- * '90.8.27 Fuzzy Debugging message add
- *
- * Function:
- * Require that all active physical maps contain no incorrect entries
- * NOW. [This update includes forcing updates of any address map
- * cashing]
- * Generally used to ensure that thread about to run will see a
- * semantically correct world.
- *
- * Parameters:
- * none
- *
- * Call:
- * cmmuflush
- *
- * The 88200 pmap implementation does not defer any operations.
- * Therefore, the translation table trees are always consistent while the
- * pmap lock is not held. Therefore, there is really no work to do in
- * this function other than to flush the TLB.
- */
-void pmap_update(void)
-{
-#ifdef DBG
- if ((pmap_con_dbg & (CD_UPD | CD_FULL)) == (CD_UPD | CD_FULL))
- printf("(pmap_update :%x) Called \n", curproc);
-#endif
-
-}/* pmap_update() */
-
-
-
-/*
- * Routine: PMAP_COLLECT
- *
- * History:
- * '90. 7.16 Fuzzy
- * '90. 7.26 Fuzzy VM_MIN_ADDRESS --> VM_MIN_USER_ADDRESS
- * VM_MIN_KERNEL_ADDRESS --> VM_MAX_USER_ADDRESS
- * '90. 7.27 Fuzzy Calls: add Macro
- * '90. 8.22 Fuzzy add Debugging message
- * '90. 9.11 Fuzzy sdt_va: vm_offset_t --> unsigned long
- *
- * Runction:
- * Garbage collects the physical map system for pages which are
- * no longer used. there may well be pages which are not
- * referenced, but others may be collected as well.
- * Called by the pageout daemon when pages are scarce.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Calls:
- * CHECK_PMAP_CONSISTENCY
- * panic
- * PMAP_LOCK, PMAP_UNLOCK
- * PT_FREE
- * pmap_pte
- * pmap_remove_range
- *
- * The intent of this routine is to release memory pages being used
- * by translation tables. They can be release only if they contain no
- * valid mappings, and their parent table entry has been invalidated.
- *
- * The routine sequences through the entries user address space,
- * inspecting page-sized groups of page tables for wired entries. If
- * a full page of tables has no wired enties, any otherwise valid
- * entries are invalidated (via pmap_remove_range). Then, the segment
- * table entries corresponding to this group of page tables are
- * invalidated. Finally, PT_FREE is called to return the page to the
- * system.
- *
- * If all entries in a segment table are invalidated, it too can
- * be returned to the system.
- *
- * [Note: depending upon compilation options, tables may be in zones
- * or allocated through kmem_alloc. In the former case, the
- * module deals with a single table at a time.]
- */
-void pmap_collect(pmap_t pmap)
-{
-
- vm_offset_t sdt_va; /* outer loop index */
- vm_offset_t sdt_vt; /* end of segment */
- sdt_entry_t *sdttbl; /* ptr to first entry in the segment table */
- sdt_entry_t *sdtp; /* ptr to index into segment table */
- sdt_entry_t *sdt; /* ptr to index into segment table */
- pt_entry_t *gdttbl; /* ptr to first entry in a page table */
- pt_entry_t *gdttblend; /* ptr to byte after last entry in table group */
- pt_entry_t *gdtp; /* ptr to index into a page table */
- boolean_t found_gdt_wired; /* flag indicating a wired page exists in */
- /* a page table's address range */
- int spl;
- unsigned int i,j;
-
-
-
- if (pmap == PMAP_NULL) {
- panic("pmap_collect: pmap is NULL");
- }
- if (pmap == kernel_pmap) {
-#ifdef MACH_KERNEL
- return;
-#else
- panic("pmap_collect attempted on kernel pmap");
-#endif
- }
-
- CHECK_PMAP_CONSISTENCY ("pmap_collect");
-
-#if DBG
- if ((pmap_con_dbg & (CD_COL | CD_NORM)) == (CD_COL | CD_NORM))
- printf ("(pmap_collect :%x) pmap %x\n", curproc, pmap);
-#endif
-
- PMAP_LOCK(pmap, spl);
-
- sdttbl = pmap->sdt_vaddr; /* addr of segment table */
- sdtp = sdttbl;
-
- /*
- This contortion is here instead of the natural loop
- because of integer overflow/wraparound if VM_MAX_USER_ADDRESS is near 0xffffffff
- */
-
- i = VM_MIN_USER_ADDRESS / PDT_TABLE_GROUP_VA_SPACE;
- j = VM_MAX_USER_ADDRESS / PDT_TABLE_GROUP_VA_SPACE;
- if ( j < 1024 ) j++;
-
- /* Segment table loop */
- for ( ; i < j; i++, sdtp += PDT_TABLE_GROUP_SIZE)
- {
- sdt_va = VM_MIN_USER_ADDRESS + PDT_TABLE_GROUP_VA_SPACE*i;
-
- gdttbl = pmap_pte(pmap, (vm_offset_t)sdt_va);
-
- if (gdttbl == PT_ENTRY_NULL)
- continue; /* no maps in this range */
-
- gdttblend = gdttbl + (PDT_ENTRIES * PDT_TABLE_GROUP_SIZE);
-
- /* scan page maps for wired pages */
- found_gdt_wired = FALSE;
- for (gdtp=gdttbl; gdtp <gdttblend; gdtp++) {
- if (gdtp->wired) {
- found_gdt_wired = TRUE;
- break;
- }
- }
-
- if (found_gdt_wired)
- continue; /* can't free this range */
-
- /* figure out end of range. Watch for wraparound */
-
- sdt_vt = sdt_va <= VM_MAX_USER_ADDRESS-PDT_TABLE_GROUP_VA_SPACE ?
- sdt_va+PDT_TABLE_GROUP_VA_SPACE :
- VM_MAX_USER_ADDRESS;
-
- /* invalidate all maps in this range */
- pmap_remove_range (pmap, (vm_offset_t)sdt_va, (vm_offset_t)sdt_vt);
-
- /*
- * we can safely deallocated the page map(s)
- */
- for (sdt = sdtp; sdt < (sdtp+PDT_TABLE_GROUP_SIZE); sdt++) {
- ((sdt_entry_template_t *) sdt) -> bits = 0;
- ((sdt_entry_template_t *) sdt+SDT_ENTRIES) -> bits = 0;
- }
-
- /*
- * we have to unlock before freeing the table, since PT_FREE
- * calls kmem_free or zfree, which will invoke another pmap routine
- */
- PMAP_UNLOCK(pmap, spl);
- PT_FREE(gdttbl);
- PMAP_LOCK(pmap, spl);
-
- } /* Segment table Loop */
-
- PMAP_UNLOCK(pmap, spl);
-
-#if DBG
- if ((pmap_con_dbg & (CD_COL | CD_NORM)) == (CD_COL | CD_NORM))
- printf ("(pmap_collect :%x) done \n", curproc);
-#endif
-
- CHECK_PMAP_CONSISTENCY("pmap_collect");
-} /* pmap collect() */
-
-
-
-/*
- * Routine: PMAP_ACTIVATE
- *
- * Author: Fuzzy
- *
- * Function:
- * Binds the given physical map to the given
- * processor, and returns a hardware map description.
- * In a mono-processor implementation the my_cpu
- * argument is ignored, and the PMAP_ACTIVATE macro
- * simply sets the MMU root pointer element of the PCB
- * to the physical address of the segment descriptor table.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * pcbp pointer to current pcb
- * cpu CPU number
- */
-void pmap_activate(pmap_t pmap, pcb_t pcb)
-{
-#ifdef lint
- my_cpu++;
-#endif
- PMAP_ACTIVATE(pmap, pcb, 0);
-} /* pmap_activate() */
-
-
-
-/*
- * Routine: PMAP_DEACTIVATE
- *
- * Author: Fuzzy
- *
- * Function:
- * Unbinds the given physical map from the given processor,
- * i.e. the pmap i no longer is use on the processor.
- * In a mono-processor the PMAP_DEACTIVATE macro is null.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * pcb pointer to pcb
- */
-void pmap_deactivate(pmap_t pmap, pcb_t pcb)
-{
-#ifdef lint
- pmap++; th++; which_cpu++;
-#endif
- PMAP_DEACTIVATE(pmap, pcb, 0);
-} /* pmap_deactivate() */
-
-
-
-/*
- * Routine: PMAP_KERNEL
- *
- * History:
- * '90. 7.16 Fuzzy unchanged
- *
- * Function:
- * Retruns a pointer to the kernel pmap.
- */
-pmap_t pmap_kernel(void)
-{
- return (kernel_pmap);
-}/* pmap_kernel() */
-
-
-/*
- * Routine: PMAP_COPY_PAGE
- *
- * History:
- * '90.7.16 Fuzzy M68K --> M88K
- * DT_PAGE --> DT_VALID
- *
- * Function:
- * Copies the specified (machine independent) pages.
- *
- * Parameters:
- * src PA of source page
- * dst PA of destination page
- *
- * Extern/Global:
- * phys_map_vaddr1
- * phys_map_vaddr2
- *
- * Calls:
- * m88kprotection
- * M88K_TRUNC_PAGE
- * cmmu_sflush_page
- * DO_PTES
- * bcopy
- *
- * Special Assumptions:
- * no locking reauired
- *
- * This routine maps the phsical pages at the 'phys_map' virtual
- * addresses set up in pmap_bootstrap. It flushes the TLB to make the
- * new mappings effective, and performs the copy.
- */
-void pmap_copy_page(vm_offset_t src, vm_offset_t dst)
-{
- vm_offset_t dstva, srcva;
- unsigned int spl_sav;
- int i;
- int aprot;
- pte_template_t template;
- pt_entry_t *dstpte, *srcpte;
- int my_cpu = cpu_number();
-
- /*
- * Map source physical address.
- */
- aprot = m88k_protection (kernel_pmap, VM_PROT_READ | VM_PROT_WRITE);
-
- srcva = (vm_offset_t)(phys_map_vaddr1 + (cpu_number() * PAGE_SIZE));
- dstva = (vm_offset_t)(phys_map_vaddr2 + (cpu_number() * PAGE_SIZE));
-
- srcpte = pmap_pte(kernel_pmap, srcva);
- dstpte = pmap_pte(kernel_pmap, dstva);
-
- for (i=0; i < ptes_per_vm_page; i++, src += M88K_PGBYTES, dst += M88K_PGBYTES)
- {
- template.bits = M88K_TRUNC_PAGE(src) | aprot | DT_VALID | CACHE_GLOBAL;
-
- /* do we need to write back dirty bits */
- spl_sav = splblock();
- cmmu_flush_tlb(1, srcva, M88K_PGBYTES);
- *srcpte = template.pte;
-
- /*
- * Map destination physical address.
- */
- template.bits = M88K_TRUNC_PAGE(dst) | aprot | CACHE_GLOBAL | DT_VALID;
- cmmu_flush_tlb(1, dstva, M88K_PGBYTES);
- *dstpte = template.pte;
- splx(spl_sav);
-
- bcopy((void*)srcva, (void*)dstva, M88K_PGBYTES);
- /* flush source, dest out of cache? */
- cmmu_flush_remote_data_cache(my_cpu, src, M88K_PGBYTES);
- cmmu_flush_remote_data_cache(my_cpu, dst, M88K_PGBYTES);
- }
-
-} /* pmap_copy_page() */
-
-
-/*
- * copy_to_phys
- *
- * Author: Fuzzy
- * History:
- * 10/17/90 take out of pmap.c of SUN3, and modify for m88k
- *
- * Copy virtual memory to physical memory by mapping the physical
- * memory into virtual memory and then doing a virtual to virtual
- * copy with bcopy.
- *
- * Parameters:
- * srcva VA of source page
- * dstpa PA of destination page
- * bytecount copy byte size
- *
- * Extern/Global:
- * phys_map_vaddr2
- *
- * Calls:
- * m88kprotection
- * M88K_TRUNC_PAGE
- * cmmu_sflush_page
- * DO_PTES
- * bcopy
- *
- */
-void copy_to_phys(
- register vm_offset_t srcva,
- register vm_offset_t dstpa,
- register int bytecount)
-{
- register vm_offset_t dstva;
- register pt_entry_t *dstpte;
- register int copy_size, offset;
- int aprot;
- unsigned int i;
- pte_template_t template;
-
- dstva = (vm_offset_t)(phys_map_vaddr2 + (cpu_number() * PAGE_SIZE));
- dstpte = pmap_pte(kernel_pmap, dstva);
- copy_size = M88K_PGBYTES;
- offset = dstpa - M88K_TRUNC_PAGE(dstpa);
- dstpa -= offset;
-
- aprot = m88k_protection(kernel_pmap, VM_PROT_READ | VM_PROT_WRITE);
- while (bytecount > 0){
- copy_size = M88K_PGBYTES - offset;
- if (copy_size > bytecount)
- copy_size = bytecount;
-
- /*
- * Map distation physical address.
- */
-
- for (i = 0; i < ptes_per_vm_page; i++)
- {
- template.bits = M88K_TRUNC_PAGE(dstpa) | aprot | CACHE_WT | DT_VALID;
- cmmu_flush_tlb(1, dstva, M88K_PGBYTES);
- *dstpte = template.pte;
-
- dstva += offset;
- bcopy((void*)srcva, (void*)dstva, copy_size);
- srcva += copy_size;
- dstva += copy_size;
- dstpa += M88K_PGBYTES;
- bytecount -= copy_size;
- offset = 0;
- }
- }
-}
-
-/*
- * copy_from_phys
- *
- * Author: David Rudolph
- * History:
- *
- * Copy physical memory to virtual memory by mapping the physical
- * memory into virtual memory and then doing a virtual to virtual
- * copy with bcopy.
- *
- * Parameters:
- * srcpa PA of source page
- * dstva VA of destination page
- * bytecount copy byte size
- *
- * Extern/Global:
- * phys_map_vaddr2
- *
- * Calls:
- * m88kprotection
- * M88K_TRUNC_PAGE
- * cmmu_sflush_page
- * DO_PTES
- * bcopy
- *
- */
-void copy_from_phys(
- register vm_offset_t srcpa,
- register vm_offset_t dstva,
- register int bytecount)
-{
- register vm_offset_t srcva;
- register pt_entry_t *srcpte;
- register int copy_size, offset;
- int aprot;
- unsigned int i;
- pte_template_t template;
-
- srcva = (vm_offset_t)(phys_map_vaddr2 + (cpu_number() * PAGE_SIZE));
- srcpte = pmap_pte(kernel_pmap, srcva);
- copy_size = M88K_PGBYTES;
- offset = srcpa - M88K_TRUNC_PAGE(srcpa);
- srcpa -= offset;
-
- aprot = m88k_protection(kernel_pmap, VM_PROT_READ | VM_PROT_WRITE);
- while (bytecount > 0){
- copy_size = M88K_PGBYTES - offset;
- if (copy_size > bytecount)
- copy_size = bytecount;
-
- /*
- * Map destnation physical address.
- */
-
- for (i=0; i < ptes_per_vm_page; i++)
- {
- template.bits = M88K_TRUNC_PAGE(srcpa) | aprot | CACHE_WT | DT_VALID;
- cmmu_flush_tlb(1, srcva, M88K_PGBYTES);
- *srcpte = template.pte;
-
- srcva += offset;
- bcopy((void*)srcva, (void*)dstva, copy_size);
- srcpa += M88K_PGBYTES;
- dstva += copy_size;
- srcva += copy_size;
- bytecount -= copy_size;
- offset = 0;
- /* cache flush source? */
- }
- }
-}
-
-/*
- * Routine: PMAP_PAGEABLE
- *
- * History:
- * '90.7.16 Fuzzy
- *
- * Function:
- * Make the specified pages (by pmap, offset) pageable (or not) as
- * requested. A page which is not pageable may not take a fault;
- * therefore, its page table entry must remain valid for the duration.
- * this routine is merely advisory; pmap_enter will specify that
- * these pages are to be wired down (or not) as appropriate.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * start virtual address of start of range
- * end virtual address of end of range
- * pageable flag indicating whether range is to be pageable.
- *
- * This routine currently does nothing in the 88100 implemetation.
- */
-void pmap_pageable(
- pmap_t pmap,
- vm_offset_t start,
- vm_offset_t end,
- boolean_t pageable)
-{
-#ifdef lint
- pmap++; start++; end++; pageable++;
-#endif
-} /* pmap_pagealbe() */
-
-
-
-/*
- * Routine: PMAP_REDZONE
- *
- * History:
- * '90.7.16 Fuzzy m68k --> m88K
- * pte protection & supervisor bit
- *
- * Function:
- * Give the kernel read-only access to the specified address. This
- * is used to detect stack overflows. It is assumed that the address
- * specified is the last possible kernel stack address. Therefore, we
- * round up to the nearest machine dependent page.
- *
- * Parameters:
- * pmap pointer to pmap structure
- * addr virtual address of page to which access should
- * be restricted to read-only
- *
- * Calls:
- * M88K_ROUND_PAGE
- * PMAP_LOCK
- * pmap_pte
- * PDT_VALID
- *
- * This function calls pmap_pte to obtain a pointer to the page
- * table entry associated with the given virtual address. If there is a
- * page entry, and it is valid, its write protect bit will be set.
- */
-void pmap_redzone(pmap_t pmap, vm_offset_t va)
-{
- pt_entry_t *pte;
- int spl, spl_sav;
- register int i;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- va = M88K_ROUND_PAGE(va);
- PMAP_LOCK(pmap, spl);
-
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- if ((pte = pmap_pte(pmap, va)) != PT_ENTRY_NULL && PDT_VALID(pte))
- for (i = ptes_per_vm_page; i > 0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- opte.pte.prot = M88K_RO;
- ((pte_template_t *)pte)->bits = opte.bits;
- flush_atc_entry(users, va, kflush);
- splx(spl_sav);
- pte++;
- va +=M88K_PGBYTES;
- }
-
- PMAP_UNLOCK(pmap, spl);
-
-} /* pmap_redzone() */
-
-
-
-/*
- * Routine: PMAP_CLEAR_MODIFY
- *
- * Author: Fuzzy
- *
- * History:
- * '90.7.24 Fuzzy
- * '90.8.21 Fuzzy Debugging message add
- *
- * Function:
- * Clear the modify bits on the specified physical page.
- *
- * Parameters:
- * phys physical address of page
- *
- * Extern/Global:
- * pv_head_table, pv_lists
- * pmap_modify_list
- *
- * Calls:
- * PMAP_MANAGED
- * SPLVM, SPLX
- * PFIDX
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * simple_lock, simple_unlock
- * pmap_pte
- * panic
- *
- * For managed pages, the modify_list entry corresponding to the
- * page's frame index will be zeroed. The PV list will be traversed.
- * For each pmap/va the hardware 'modified' bit in the page descripter table
- * entry inspected - and turned off if necessary. If any of the
- * inspected bits were found on, an TLB flush will be performed.
- */
-void pmap_clear_modify(vm_offset_t phys)
-{
- pv_entry_t pvl;
- int pfi;
- pv_entry_t pvep;
- pt_entry_t *pte;
- pmap_t pmap;
- int spl, spl_sav;
- register vm_offset_t va;
- register int i;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (!PMAP_MANAGED(phys)) {
-#ifdef DBG
- if (pmap_con_dbg & CD_CMOD)
- printf("(pmap_clear_modify :%x) phys addr 0x%x not managed \n", curproc, phys);
-#endif
- return;
- }
-
- SPLVM(spl);
-
-clear_modify_Retry:
- pfi = PFIDX(phys);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST (phys, pvl, "pmap_clear_modify");
-
- /* update correspoinding pmap_modify_list element */
- pmap_modify_list[pfi] = 0;
-
- if (pvl->pmap == PMAP_NULL) {
-#ifdef DEBUG
- if ((pmap_con_dbg & (CD_CMOD | CD_NORM)) == (CD_CMOD | CD_NORM))
- printf("(pmap_clear_modify :%x) phys addr 0x%x not mapped\n", curproc, phys);
-#endif
-
- SPLX(spl);
- return;
- }
-
- /* for each listed pmap, trun off the page modified bit */
- pvep = pvl;
- while (pvep != PV_ENTRY_NULL) {
- pmap = pvep->pmap;
- va = pvep->va;
- if (!simple_lock_try(&pmap->lock)) {
- goto clear_modify_Retry;
- }
-
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- pte = pmap_pte(pmap, va);
- if (pte == PT_ENTRY_NULL)
- panic("pmap_clear_modify: bad pv list entry.");
-
- for (i = ptes_per_vm_page; i > 0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- /* clear modified bit */
- opte.pte.modified = 0;
- ((pte_template_t *)pte)->bits = opte.bits;
- flush_atc_entry(users, va, kflush);
- splx(spl_sav);
- pte++;
- va += M88K_PGBYTES;
- }
-
- simple_unlock(&pmap->lock);
-
- pvep = pvep->next;
- }
-
- SPLX(spl);
-
-} /* pmap_clear_modify() */
-
-
-
-/*
- * Routine: PMAP_IS_MODIFIED
- *
- * History:
- * '90. 7.16 Fuzzy
- * '90. 7.19 Fuzzy comments 'Calls'
- * '90. 8.20 Fuzzy Added debugging message
- * '90. 8.20 Fuzzy when panic, print virt_address
- *
- * Function:
- * Return whether or not the specified physical page is modified
- * by any physical maps. That is, whether the hardware has
- * stored data into the page.
- *
- * Parameters:
- * phys physical address og a page
- *
- * Extern/Global:
- * pv_head_array, pv lists
- * pmap_modify_list
- *
- * Calls:
- * simple_lock, simple_unlock
- * SPLVM, SPLX
- * PMAP_MANAGED
- * PFIDX
- * PFIDX_TO_PVH
- * pmap_pte
- *
- * If the physical address specified is not a managed page, this
- * routine simply returns TRUE (looks like it is returning FALSE XXX).
- *
- * If the entry in the modify list, corresponding to the given page,
- * is TRUE, this routine return TRUE. (This means at least one mapping
- * has been invalidated where the MMU had set the modified bit in the
- * page descripter table entry (PTE).
- *
- * Otherwise, this routine walks the PV list corresponding to the
- * given page. For each pmap/va pair, the page descripter table entry is
- * examined. If a modified bit is found on, the function returns TRUE
- * immediately (doesn't need to walk remainder of list).
- */
-boolean_t pmap_is_modified(vm_offset_t phys)
-{
- pv_entry_t pvl;
- int pfi;
- pv_entry_t pvep;
- pt_entry_t *ptep;
- int spl;
- int i;
- boolean_t modified_flag;
-
- if (!PMAP_MANAGED(phys)) {
-#ifdef DBG
- if (pmap_con_dbg & CD_IMOD)
- printf("(pmap_is_modified :%x) phys addr 0x%x not managed\n", curproc, phys);
-#endif
- return(FALSE);
- }
-
- SPLVM(spl);
-
- pfi = PFIDX(phys);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST (phys, pvl, "pmap_is_modified");
-is_mod_Retry:
-
- if ((boolean_t) pmap_modify_list[pfi]) {
- /* we've already cached a modify flag for this page,
- no use looking further... */
-#ifdef DBG
- if ((pmap_con_dbg & (CD_IMOD | CD_NORM)) == (CD_IMOD | CD_NORM))
- printf("(pmap_is_modified :%x) already cached a modify flag for this page\n", curproc);
-#endif
- SPLX(spl);
- return(TRUE);
- }
-
- if (pvl->pmap == PMAP_NULL) {
- /* unmapped page - get info from page_modified array
- maintained by pmap_remove_range/ pmap_remove_all */
- modified_flag = (boolean_t) pmap_modify_list[pfi];
-#ifdef DBG
- if ((pmap_con_dbg & (CD_IMOD | CD_NORM)) == (CD_IMOD | CD_NORM))
- printf("(pmap_is_modified :%x) phys addr 0x%x not mapped\n", curproc, phys);
-#endif
- SPLX(spl);
- return(modified_flag);
- }
-
- /* for each listed pmap, check modified bit for given page */
- pvep = pvl;
- while (pvep != PV_ENTRY_NULL) {
- if (!simple_lock_try(&pvep->pmap->lock)) {
- UNLOCK_PVH(pfi);
- goto is_mod_Retry;
- }
-
- ptep = pmap_pte(pvep->pmap, pvep->va);
- if (ptep == PT_ENTRY_NULL) {
- printf("pmap_is_modified: pte from pv_list not in map virt = 0x%x\n", pvep->va);
- panic("pmap_is_modified: bad pv list entry");
- }
- for (i = ptes_per_vm_page; i > 0; i--) {
- if (ptep->modified) {
- simple_unlock(&pvep->pmap->lock);
-#ifdef DBG
- if ((pmap_con_dbg & (CD_IMOD | CD_FULL)) == (CD_IMOD | CD_FULL))
- printf("(pmap_is_modified :%x) modified page pte@0x%x\n", curproc, (unsigned)ptep);
-#endif
- SPLX(spl);
- return(TRUE);
- }
- ptep++;
- }
- simple_unlock(&pvep->pmap->lock);
-
- pvep = pvep->next;
- }
-
- SPLX(spl);
- return(FALSE);
-
-} /* pmap_is_modified() */
-
-
-
-/*
- * Routine: PMAP_CLEAR_REFERECE
- *
- * History:
- * '90. 7.16 Fuzzy unchanged
- * '90. 7.19 Fuzzy comment "Calls:' add
- * '90. 8.21 Fuzzy Debugging message add
- * '93. 3. 1 jfriedl Added call to LOCK_PVH
- *
- * Function:
- * Clear the reference bits on the specified physical page.
- *
- * Parameters:
- * phys physical address of page
- *
- * Calls:
- * PMAP_MANAGED
- * SPLVM, SPLX
- * PFIDX
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * simple_lock
- * pmap_pte
- * panic
- *
- * Extern/Global:
- * pv_head_array, pv lists
- *
- * For managed pages, the coressponding PV list will be traversed.
- * For each pmap/va the hardware 'used' bit in the page table entry
- * inspected - and turned off if necessary. If any of the inspected bits
- * werw found on, an TLB flush will be performed.
- */
-void pmap_clear_reference(vm_offset_t phys)
-{
- pv_entry_t pvl;
- int pfi;
- pv_entry_t pvep;
- pt_entry_t *pte;
- pmap_t pmap;
- int spl, spl_sav;
- register vm_offset_t va;
- register int i;
- register unsigned users;
- register pte_template_t opte;
- int kflush;
-
- if (!PMAP_MANAGED(phys)) {
-#ifdef DBG
- if (pmap_con_dbg & CD_CREF) {
- printf("(pmap_clear_reference :%x) phys addr 0x%x not managed\n", curproc,phys);
- }
-#endif
- return;
- }
-
- SPLVM(spl);
-
-clear_reference_Retry:
- pfi = PFIDX(phys);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST(phys, pvl, "pmap_clear_reference");
-
-
- if (pvl->pmap == PMAP_NULL) {
-#ifdef DBG
- if ((pmap_con_dbg & (CD_CREF | CD_NORM)) == (CD_CREF | CD_NORM))
- printf("(pmap_clear_reference :%x) phys addr 0x%x not mapped\n", curproc,phys);
-#endif
- SPLX(spl);
- return;
- }
-
- /* for each listed pmap, turn off the page refrenced bit */
- pvep = pvl;
- while (pvep != PV_ENTRY_NULL) {
- pmap = pvep->pmap;
- va = pvep->va;
- if (!simple_lock_try(&pmap->lock)) {
- goto clear_reference_Retry;
- }
-
- users = 0;
- if (pmap == kernel_pmap) {
- kflush = 1;
- } else {
- kflush = 0;
- }
-
- pte = pmap_pte(pmap, va);
- if (pte == PT_ENTRY_NULL)
- panic("pmap_clear_reference: bad pv list entry.");
-
- for (i = ptes_per_vm_page; i > 0; i--) {
-
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- spl_sav = splblock();
- opte.bits = invalidate_pte(pte);
- /* clear reference bit */
- opte.pte.pg_used = 0;
- ((pte_template_t *)pte)->bits = opte.bits;
- flush_atc_entry(users, va, kflush);
- splx(spl_sav);
- pte++;
- va += M88K_PGBYTES;
- }
-
- simple_unlock(&pmap->lock);
-
- pvep = pvep->next;
- }
-
- SPLX(spl);
-
-} /* pmap_clear_reference() */
-
-
-
-/*
- * Routine: PMAP_IS_REFERENCED
- *
- * History:
- * '90. 7.16 Fuzzy
- * '90. 7.19 Fuzzy comment 'Calls:' add
- *
- * Function:
- * Retrun whether or not the specifeid physical page is referenced by
- * any physical maps. That is, whether the hardware has touched the page.
- *
- * Parameters:
- * phys physical address of a page
- *
- * Extern/Global:
- * pv_head_array, pv lists
- *
- * Calls:
- * PMAP_MANAGED
- * SPLVM
- * PFIDX
- * PFIDX_TO_PVH
- * CHECK_PV_LIST
- * simple_lock
- * pmap_pte
- *
- * If the physical address specified is not a managed page, this
- * routine simply returns TRUE.
- *
- * Otherwise, this routine walks the PV list corresponding to the
- * given page. For each pmap/va/ pair, the page descripter table entry is
- * examined. If a used bit is found on, the function returns TRUE
- * immediately (doesn't need to walk remainder of list).
- */
-boolean_t pmap_is_referenced(vm_offset_t phys)
-{
- pv_entry_t pvl;
- int pfi;
- pv_entry_t pvep;
- pt_entry_t *ptep;
- int spl;
- int i;
-
- if (!PMAP_MANAGED(phys))
- return(FALSE);
-
- SPLVM(spl);
-
- pfi = PFIDX(phys);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST(phys, pvl, "pmap_is_referenced");
-
-is_ref_Retry:
-
- if (pvl->pmap == PMAP_NULL) {
- SPLX(spl);
- return(FALSE);
- }
-
- /* for each listed pmap, check used bit for given page */
- pvep = pvl;
- while (pvep != PV_ENTRY_NULL) {
- if (!simple_lock_try(&pvep->pmap->lock)) {
- UNLOCK_PVH(pfi);
- goto is_ref_Retry;
- }
-
- ptep = pmap_pte(pvep->pmap, pvep->va);
- if (ptep == PT_ENTRY_NULL)
- panic("pmap_is_referenced: bad pv list entry.");
- for (i = ptes_per_vm_page; i > 0; i--) {
- if (ptep->pg_used) {
- simple_unlock(&pvep->pmap->lock);
- SPLX(spl);
- return(TRUE);
- }
- ptep++;
- }
- simple_unlock(&pvep->pmap->lock);
-
- pvep = pvep->next;
- }
-
- SPLX(spl);
- return(FALSE);
-} /* pmap_is referenced() */
-
-/*
- * Routine: PMAP_VERIFY_FREE
- *
- * History:
- * '90. 7.17 Fuzzy This routine extract vax's pmap.c.
- * This do not exit in m68k's pmap.c.
- * vm_page_alloc calls this.
- * Variables changed below,
- * vm_first_phys --> pmap_phys_start
- * vm_last_phys --> pmap_phys_end
- * Macro chnged below,
- * pa_index --> PFIDX
- * pai_to_pvh --> PFI_TO_PVH
- *
- * Calls:
- * SPLVM, SPLX
- * PFIDX
- * PFI_TO_PVH
- *
- * Global/Extern:
- * pmap_initialized
- * pmap_phys_start
- * pmap_phys_end
- * TRUE, FALSE
- * PMAP_NULL
- *
- * This routine check physical address if that have pmap modules.
- * It returns TRUE/FALSE.
- */
-
-boolean_t pmap_verify_free(vm_offset_t phys)
-{
- pv_entry_t pv_h;
- int spl;
- boolean_t result;
-
- if (!pmap_initialized)
- return(TRUE);
-
- if (!PMAP_MANAGED(phys))
- return(FALSE);
-
- SPLVM(spl);
-
- pv_h = PFIDX_TO_PVH(PFIDX(phys));
-
- result = (pv_h->pmap == PMAP_NULL);
- SPLX(spl);
-
- return(result);
-
-} /* pmap_verify_free */
-
-
-/*
- * Routine: PMAP_VALID_PAGE
- *
- * History:
- * '90.7.18 Fuzzy This function do not exist in m68K pmap list.
- * vm_page_startup() routine calls this.
- *
- * The physical address space is dense... there are no holes.
- * All addresses provided to vm_page_startup() are valid.
- */
-boolean_t pmap_valid_page(vm_offset_t p)
-{
-#ifdef lint
- p++;
-#endif
- return(TRUE);
-} /* pmap_valid_page() */
-
-/*
- * Routine: PMAP_PAGE_PROTECT
- *
- * History:
- * '90.8.4 Fuzzy extract vax pmap.c
- *
- * Calls:
- * pmap_copy_on_write
- * pmap_remove_all
- *
- * Lower the permission for all mappings to a given page.
- */
-void pmap_page_protect(vm_offset_t phys, vm_prot_t prot)
-{
- switch (prot) {
- case VM_PROT_READ:
- case VM_PROT_READ|VM_PROT_EXECUTE:
- pmap_copy_on_write(phys);
- break;
- case VM_PROT_ALL:
- break;
- default:
- pmap_remove_all(phys);
- break;
- }
-}
-
-#if 0
-/*
- * Routine: PAGEMOVE
- *
- * History:
- *
- * 11/08/09 N.Sugai Initial version
- *
- * Function:
- * Move pages from one kernel virtual address to another.
- *
- * Parameters:
- * from kernel virtual address of source
- * to kernel virtual address of distination
- * size size in bytes
- *
- * Calls:
- * PMAP_LOCK
- * PMAP_UNLOCK
- * LOCK_PVH
- * UNLOCK_PVH
- * CHECK_PV_LIST
- * pmap_pte
- * pmap_expand_kmap
- * cmmu_sflush
- *
- * Special Assumptions:
- * size must be a multiple of CLBYTES (?)
- */
-void pagemove(vm_offset_t from, vm_offset_t to, int size)
-{
- vm_offset_t pa;
- pt_entry_t *srcpte, *dstpte;
- int pfi;
- pv_entry_t pvl;
- int spl;
- register int i;
- register unsigned users;
- register pte_template_t opte;
-
- PMAP_LOCK(kernel_pmap, spl);
-
- users = 0;
-
- while (size > 0) {
-
- /*
- * check if the source addr is mapped
- */
- if ((srcpte = pmap_pte(kernel_pmap, (vm_offset_t)from)) == PT_ENTRY_NULL) {
- printf("pagemove: source vaddr 0x%x\n", from);
- panic("pagemove: Source addr not mapped");
- }
-
- /*
- *
- */
- if ((dstpte = pmap_pte(kernel_pmap, (vm_offset_t)to)) == PT_ENTRY_NULL)
- if ((dstpte = pmap_expand_kmap((vm_offset_t)to, VM_PROT_READ | VM_PROT_WRITE))
- == PT_ENTRY_NULL)
- panic("pagemove: Cannot allocate distination pte");
- /*
- *
- */
- if (dstpte->dtype == DT_VALID) {
- printf("pagemove: distination vaddr 0x%x, pte = 0x%x\n", to, *((unsigned *)dstpte));
- panic("pagemove: Distination pte already valid");
- }
-
-#ifdef DBG
- if ((pmap_con_dbg & (CD_PGMV | CD_NORM)) == (CD_PGMV | CD_NORM))
- printf("(pagemove :%x) from 0x%x to 0x%x\n", curproc, from, to);
- if ((pmap_con_dbg & (CD_PGMV | CD_FULL)) == (CD_PGMV | CD_FULL))
- printf("(pagemove :%x) srcpte @ 0x%x = %x dstpte @ 0x%x = %x\n", curproc, (unsigned)srcpte, *(unsigned *)srcpte, (unsigned)dstpte, *(unsigned *)dstpte);
-
-#endif /* DBG */
-
- /*
- * Update pv_list
- */
- pa = M88K_PTOB(srcpte->pfn);
- if (PMAP_MANAGED(pa)) {
- pfi = PFIDX(pa);
- pvl = PFIDX_TO_PVH(pfi);
- CHECK_PV_LIST(pa, pvl, "pagemove");
- pvl->va = (vm_offset_t)to;
- }
-
- /*
- * copy pte
- */
- for (i = ptes_per_vm_page; i > 0; i--) {
- /*
- * Invalidate pte temporarily to avoid being written back
- * the modified bit and/or the reference bit by other cpu.
- */
- opte.bits = invalidate_pte(srcpte);
- flush_atc_entry(users, from, 1);
- ((pte_template_t *)dstpte)->bits = opte.bits;
- from += M88K_PGBYTES;
- to += M88K_PGBYTES;
- srcpte++; dstpte++;
- }
- size -= PAGE_SIZE;
- }
-
- PMAP_UNLOCK(kernel_pmap, spl);
-
-} /* pagemove */
-
-#endif /* 0 */
-/*
- * Routine: icache_flush
- *
- * Function:
- * Invalidate instruction cache for all CPUs on specified
- * physical address. Called when a page is removed from a
- * vm_map. This is done because the Instruction CMMUs are not
- * snooped, and if a page is subsequently used as a text page,
- * we want the CMMUs to re-load the cache for the page.
- *
- * Parameters:
- * pa physical address of the (vm) page
- *
- * Extern/globals:
- * ptes_per_vm_page
- *
- * Calls:
- * cachefall
- *
- * Called by:
- * vm_remove_page
- *
- */
-void icache_flush(vm_offset_t pa)
-{
- register int i;
- register int cpu = 0;
-
- for (i = ptes_per_vm_page; i > 0; i--, pa += M88K_PGBYTES) {
- cmmu_flush_remote_inst_cache(cpu, pa, M88K_PGBYTES);
- }
-
-} /* icache_flush */
-
-/*
- * Routine: pmap_dcache_flush
- *
- * Function:
- * Flush DATA cache on specified virtual address.
- *
- * Parameters:
- * pmap specify pmap
- * va virtual address of the (vm) page to be flushed
- *
- * Extern/globals:
- * pmap_pte
- * ptes_per_vm_page
- *
- * Calls:
- * dcacheflush
- *
- */
-void pmap_dcache_flush(pmap_t pmap, vm_offset_t va)
-{
- register vm_offset_t pa;
- register int i;
- int spl;
-
- if (pmap == PMAP_NULL)
- panic("pmap_dcache_flush: pmap is NULL");
-
- PMAP_LOCK(pmap, spl);
-
- pa = M88K_PTOB((pmap_pte(pmap, va))->pfn);
- for (i = ptes_per_vm_page; i > 0; i--, pa += M88K_PGBYTES) {
- cmmu_flush_data_cache(pa, M88K_PGBYTES);
- }
-
- PMAP_UNLOCK(pmap, spl);
-
-
-} /* pmap_dcache_flush */
-
-static void cache_flush_loop(int mode, vm_offset_t pa, int size)
-{
- register int i;
- register int ncpus;
- void (*cfunc)(int cpu, vm_offset_t physaddr, int size);
-
- switch (mode) {
- default:
- panic("bad cache_flush_loop mode");
- return;
-
- case FLUSH_CACHE: /* All caches, all CPUs */
- ncpus = NCPUS;
- cfunc = cmmu_flush_remote_cache;
- break;
-
- case FLUSH_CODE_CACHE: /* Instruction caches, all CPUs */
- ncpus = NCPUS;
- cfunc = cmmu_flush_remote_inst_cache;
- break;
-
- case FLUSH_DATA_CACHE: /* Data caches, all CPUs */
- ncpus = NCPUS;
- cfunc = cmmu_flush_remote_data_cache;
- break;
-
- case FLUSH_LOCAL_CACHE: /* Both caches, my CPU */
- ncpus = 1;
- cfunc = cmmu_flush_remote_cache;
- break;
-
- case FLUSH_LOCAL_CODE_CACHE: /* Instruction cache, my CPU */
- ncpus = 1;
- cfunc = cmmu_flush_remote_inst_cache;
- break;
-
- case FLUSH_LOCAL_DATA_CACHE: /* Data cache, my CPU */
- ncpus = 1;
- cfunc = cmmu_flush_remote_data_cache;
- break;
- }
-
- if (ncpus == 1) {
- (*cfunc)(cpu_number(), pa, size);
- }
- else {
- for (i=0; i<NCPUS; i++) {
- (*cfunc)(i, pa, size);
- }
- }
-}
-
-/*
- * pmap_cache_flush
- * Internal function.
- */
-void pmap_cache_flush(
- pmap_t pmap,
- vm_offset_t virt,
- int bytes,
- int mode)
-{
- register vm_offset_t pa;
- register vm_offset_t va;
- register int i;
- int spl;
-
- if (pmap == PMAP_NULL)
- panic("pmap_dcache_flush: NULL pmap");
-
- /*
- * If it is more than a couple of pages, just blow the whole cache
- * because of the number of cycles involved.
- */
- if (bytes > 2*M88K_PGBYTES) {
- cache_flush_loop(mode, 0, -1);
- return;
- }
-
- PMAP_LOCK(pmap, spl);
- for(va = virt; bytes > 0; bytes -= M88K_PGBYTES,va += M88K_PGBYTES) {
- pa = M88K_PTOB((pmap_pte(pmap, va))->pfn);
- for (i = ptes_per_vm_page; i > 0; i--, pa += M88K_PGBYTES) {
- cache_flush_loop(mode, pa, M88K_PGBYTES);
- }
- }
- PMAP_UNLOCK(pmap, spl);
-} /* pmap_ccacheflush */
-
-
-#ifdef JUNK
-/*
- * Machine-level page attributes
- *
- * This implementation was lifted from the MIPS pmap module.
- * We currently only use it to invalidate the I-Cache for
- * debugger use.
- *
- * These are infrequently used features of the M88K CMMU,
- * basically cache control functions. The cachability
- * property of mappings must be remembered across paging
- * operations, so that they can be restored on need.
- *
- * Obviously these attributes will be used in a sparse
- * fashion, so we use a simple list of attribute-value
- * pairs.
- *
- * Some notes on the cache management based upon my quick
- * calculation and previous experience.
- * We must carefully weigh the cost of cache invalidate time to
- * cache refill time. If "cachefall()" is called for more than
- * two pages, it is usually faster to simply invalidate the entire
- * cache and let it refill, since the number of cycles required to
- * perform the invalidate becomes greater than the number to refill.
- * If we are only performing an invalidate for something like a
- * debugger breakpoint, it becomes worthwhile to only perform a
- * line invalidate. Remember, we must account for the amount of
- * time required to perform the pmap lookups.
- */
-/*
- * pmap_attributes:
- *
- * Set/Get special memory attributes
- *
- * This is currently only used to invalidate the I-cache when a
- * breakpoint is set by the debugger.
- *
- */
-int pmap_attribute(
- pmap_t pmap,
- vm_offset_t address,
- vm_size_t size,
- vm_machine_attribute_t attribute,
- vm_machine_attribute_val_t* value) /* IN/OUT */
-{
- register vm_offset_t start, end;
- int ret;
-#ifdef notyet
- pmap_attribute_t a;
-#endif
-
- if (attribute != MATTR_CACHE)
- return KERN_INVALID_ARGUMENT;
-
- if (pmap == PMAP_NULL)
- return KERN_SUCCESS;
-
- start = trunc_page(address);
- end = round_page(address + size);
- ret = KERN_SUCCESS;
-
-
- /* All we are looking for right now is an instruction cache flush.
- */
- switch(*value) {
- case MATTR_VAL_CACHE_FLUSH:
- pmap_cache_flush(pmap, start, size, FLUSH_CACHE);
- break;
- case MATTR_VAL_DCACHE_FLUSH:
- pmap_cache_flush(pmap, start, size, FLUSH_DATA_CACHE);
- break;
- case MATTR_VAL_ICACHE_FLUSH:
- pmap_cache_flush(pmap, start, size, FLUSH_CODE_CACHE);
- /* ptrace_user_iflush(pmap, start, size); */
- break;
-
- default:
- ret = KERN_INVALID_ARGUMENT;
- }
-
- return ret;
-}
-#endif /* JUNK */
-#ifdef DEBUG
-/*
- * DEBUGGING ROUTINES - check_pv_list and check_pmp_consistency are used
- * only for debugging. They are invoked only
- * through the macros CHECK_PV_LIST AND CHECK_PMAP_CONSISTENCY
- * defined early in this sourcefile.
- */
-
-/*
- * Routine: CHECK_PV_LIST (internal)
- *
- * History:
- * '90.7.13 Fuzzy
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- * Function:
- * Debug-mode routine to check consistency of a PV list. First, it
- * makes sure every map thinks the physical page is the same. This
- * should be called by all routines which touch a PV list.
- *
- * Parameters:
- * phys physical address of page whose PV list is
- * to be checked
- * pv_h pointer to head to the PV list
- * who string containing caller's name to be
- * printed if a panic arises
- *
- * Extern/Global:
- * pv_head_array, pv lists
- *
- * Calls:
- * pmap_extract
- *
- * Special Assumptions:
- * No locking is required.
- *
- * This function walks the given PV list. For each pmap/va pair,
- * pmap_extract is called to obtain the physical address of the page from
- * the pmap in question. If the retruned physical address does not match
- * that for the PV list being perused, the function panics.
- */
-
-static void check_pv_list(vm_offset_t phys, pv_entry_t pv_h, char *who)
-{
- pv_entry_t pv_e;
- pt_entry_t *pte;
- vm_offset_t pa;
-
- if (pv_h != PFIDX_TO_PVH(PFIDX(phys))) {
- printf("check_pv_list: incorrect pv_h supplied.\n");
- panic(who);
- }
-
- if (!PAGE_ALIGNED(phys)) {
- printf("check_pv_list: supplied phys addr not page aligned.\n");
- panic(who);
- }
-
- if (pv_h->pmap == PMAP_NULL) {
- if (pv_h->next != PV_ENTRY_NULL) {
- printf("check_pv_list: first entry has null pmap, but list non-empty.\n");
- panic(who);
- }
- else return; /* proper empry lst */
- }
-
- pv_e = pv_h;
- while (pv_e != PV_ENTRY_NULL) {
- if (!PAGE_ALIGNED(pv_e->va)) {
- printf("check_pv_list: non-aligned VA in entry at 0x%x.\n", pv_e);
- panic(who);
- }
- /*
- * We can't call pmap_extract since it requires lock.
- */
- if ((pte = pmap_pte(pv_e->pmap, pv_e->va)) == PT_ENTRY_NULL)
- pa = (vm_offset_t)0;
- else
- pa = M88K_PTOB(pte->pfn) | (pv_e->va & M88K_PGOFSET);
-
- if (pa != phys) {
- printf("check_pv_list: phys addr diff in entry at 0x%x.\n", pv_e);
- panic(who);
- }
-
- pv_e = pv_e->next;
- }
-
-} /* check_pv_list() */
-
-/*
- * Routine: CHECK_MAP (itnernal)
- *
- * History:
- * June 13 '90 Fuzzy
- * Rewrite level 1 --> segment
- * level 3 --> page
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- *
- * Function:
- * Debug mode routine to check consistency of map.
- * Called by check_pmap_consistency only.
- *
- * Parameters:
- * map pointer to pmap structure
- * s start of range to be checked
- * e end of range to be checked
- * who string containing caller's name to be
- * printed if a panic arises
- *
- * Extern/Global:
- * pv_head_array, pv lists
- *
- * Calls:
- * pmap_pte
- *
- * Special Assumptions:
- * No locking required.
- *
- * This function sequences through the given range of addresses. For
- * each page, pmap_pte is called to obtain the page table entry. If
- * its valid, and the physical page it maps is managed, the PV list is
- * searched for the corresponding pmap/va entry. If not found, the
- * function panics. If duplicate PV list entries are found, the function
- * panics.
- */
-
-static void check_map(
- pmap_t map,
- vm_offset_t s,
- vm_offset_t e,
- char *who)
-{
- vm_offset_t va,
- old_va,
- phys;
- pv_entry_t pv_h,
- pv_e,
- saved_pv_e;
- pt_entry_t *ptep;
- boolean_t found;
- int loopcnt;
-
-
- /*
- * for each page in the address space, check to see if there's
- * a valid mapping. If so makes sure it's listed in the PV_list.
- */
-
- if ((pmap_con_dbg & (CD_CHKM | CD_NORM)) == (CD_CHKM | CD_NORM))
- printf("(check_map) checking map at 0x%x\n", map);
-
- old_va = s;
- for (va = s; va < e; va += PAGE_SIZE) {
- /* check for overflow - happens if e=0xffffffff */
- if (va < old_va)
- break;
- else
- old_va = va;
-
- if (va == phys_map_vaddr1 || va == phys_map_vaddr2)
- /* don't try anything with these */
- continue;
-
- ptep = pmap_pte(map, va);
-
- if (ptep == PT_ENTRY_NULL) {
- /* no page table, skip to next segment entry */
- va = SDT_NEXT(va)-PAGE_SIZE;
- continue;
- }
-
- if (!PDT_VALID(ptep))
- continue; /* no page mapping */
-
- phys = M88K_PTOB(ptep->pfn); /* pick up phys addr */
-
- if (!PMAP_MANAGED(phys))
- continue; /* no PV list */
-
- /* note: vm_page_startup allocates some memory for itself
- through pmap_map before pmap_init is run. However,
- it doesn't adjust the physical start of memory.
- So, pmap thinks those pages are managed - but they're
- not actually under it's control. So, the following
- conditional is a hack to avoid those addresses
- reserved by vm_page_startup */
- /* pmap_init also allocate some memory for itself. */
-
- if (map == kernel_pmap &&
- va < round_page((vm_offset_t)(pmap_modify_list + (pmap_phys_end - pmap_phys_start))))
- continue;
-
- pv_h = PFIDX_TO_PVH(PFIDX(phys));
- found = FALSE;
-
- if (pv_h->pmap != PMAP_NULL) {
-
- loopcnt = 10000; /* loop limit */
- pv_e = pv_h;
- while(pv_e != PV_ENTRY_NULL) {
-
- if (loopcnt-- < 0) {
- printf("check_map: loop in PV list at PVH 0x%x (for phys 0x%x)\n", pv_h, phys);
- panic(who);
- }
-
- if (pv_e->pmap == map && pv_e->va == va) {
- if (found) {
- printf("check_map: Duplicate PV list entries at 0x%x and 0x%x in PV list 0x%x.\n", saved_pv_e, pv_e, pv_h);
- printf("check_map: for pmap 0x%x, VA 0x%x,phys 0x%x.\n", map, va, phys);
- panic(who);
- }
- else {
- found = TRUE;
- saved_pv_e = pv_e;
- }
- }
- pv_e = pv_e->next;
- }
- }
-
- if (!found) {
- printf("check_map: Mapping for pmap 0x%x VA 0x%x Phys 0x%x does not appear in PV list 0x%x.\n", map, va, phys, pv_h);
- }
- }
-
- if ((pmap_con_dbg & (CD_CHKM | CD_NORM)) == (CD_CHKM | CD_NORM))
- printf("(check_map) done \n");
-
-} /* check_map() */
-
-/*
- * Routine: CHECK_PMAP_CONSISTENCY (internal)
- *
- * History:
- * '90. 7.16 Fuzzy
- * '90.8.3 Fuzzy
- * if defined TEST, 'static' undeclared.
- * '90.8.30 Fuzzy
- * delete "if defined TEST, 'static' undeclared."
- *
- * Function:
- * Debug mode routine which walks all pmap, checking for internal
- * consistency. We are called UNLOCKED, so we'll take the write
- * lock.
- *
- * Parameters:
- * who string containing caller's name tobe
- * printed if a panic arises
- *
- * Extern/Global:
- * list of pmap structures
- *
- * Calls:
- * check map
- * check pv_list
- *
- * This function obtains the pmap write lock. Then, for each pmap
- * structure in the pmap struct queue, it calls check_map to verify the
- * consistency of its translation table hierarchy.
- *
- * Once all pmaps have been checked, check_pv_list is called to check
- * consistency of the PV lists for each managed page.
- *
- * NOTE: Added by Sugai 10/29/90
- * There are some pages do not appaer in PV list. These pages are
- * allocated for pv structures by kmem_alloc called in pmap_init.
- * Though they are in the range of pmap_phys_start to pmap_phys_end,
- * PV maniupulations had not been activated when these pages were alloceted.
- *
- */
-
-static void check_pmap_consistency(char *who)
-{
- pmap_t p;
- int i;
- vm_offset_t phys;
- pv_entry_t pv_h;
- int spl;
-
- if ((pmap_con_dbg & (CD_CHKPM | CD_NORM)) == (CD_CHKPM | CD_NORM))
- printf("check_pmap_consistency (%s :%x) start.\n", who, curproc);
-
- if (pv_head_table == PV_ENTRY_NULL) {
-
- printf("check_pmap_consistency (%s) PV head table not initialized.\n", who);
- return;
- }
-
- SPLVM(spl);
-
- p = kernel_pmap;
- check_map(p, VM_MIN_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS, who);
-
- /* run through all pmaps. check consistency of each one... */
- i = PMAP_MAX;
- for (p = kernel_pmap->next;p != kernel_pmap; p = p->next) {
- if (i == 0) { /* can not read pmap list */
- printf("check_pmap_consistency: pmap strcut loop error.\n");
- panic(who);
- }
- check_map(p, VM_MIN_USER_ADDRESS, VM_MAX_USER_ADDRESS, who);
- }
-
- /* run through all managed paes, check pv_list for each one */
- for (phys = pmap_phys_start; phys < pmap_phys_end; phys += PAGE_SIZE) {
- pv_h = PFIDX_TO_PVH(PFIDX(phys));
- check_pv_list(phys, pv_h, who);
- }
-
- SPLX(spl);
-
- if ((pmap_con_dbg & (CD_CHKPM | CD_NORM)) == (CD_CHKPM | CD_NORM))
- printf("check_pmap consistency (%s :%x): done.\n",who, curproc);
-
-} /* check_pmap_consistency() */
-#endif /* DBG */
-
-/*
- * PMAP PRINT MACROS AND ROUTINES FOR DEBUGGING
- * These routines are called only from the debugger.
- * (No locking required.)
- * usually found in pmap.c Fuzzy '90.7.12
- */
-
-#define PRINT_SDT(p) \
- printf("%08x : ", \
- ((sdt_entry_template_t *)p)-> bits); \
- printf("table adress=0x%x, prot=%d, dtype=%d\n", \
- M88K_PTOB(p->table_addr), \
- p->prot, \
- p->dtype);
-
-#define PRINT_PDT(p) \
- printf("%08x : ", \
- ((pte_template_t *)p)-> bits); \
- printf("frame num=0x%x, prot=%d, dtype=%d, wired=%d, modified=%d, pg_used=%d\n", \
- p->pfn, \
- p->prot, \
- p->dtype, \
- p->wired, \
- p->modified, \
- p->pg_used);
-
-/*
- * Routine: PMAP_PRINT
- *
- * Author: Fuzzy '90.7.12
- *
- * History:
- * '90.7.25 Fuzzy Null sdt entry skip, and skip count print.
- *
- * Function:
- * Print pmap stucture, including segment table.
- *
- * Parameters:
- * pmap pointer to pmap structure
- *
- * Special Assumptions:
- * No locking required.
- *
- * This function prints the fields of the pmap structure, then
- * iterates through the segment translation table, printing each entry.
- */
-void pmap_print (pmap_t pmap)
-{
- sdt_entry_t *sdtp;
- sdt_entry_t *sdtv;
- int i;
-
- printf("Pmap @ 0x%x:\n", (unsigned)pmap);
- sdtp = pmap->sdt_paddr;
- sdtv = pmap->sdt_vaddr;
- printf(" sdt_paddr: 0x%x; sdt_vaddr: 0x%x; ref_count: %d;\n",
- (unsigned)sdtp, (unsigned)sdtv,
- pmap->ref_count);
-
-#ifdef statistics_not_yet_maintained
- printf(" statistics: pagesize %d: free_count %d; "
- "active_count %d; inactive_count %d; wire_count %d\n",
- pmap->stats.pagesize,
- pmap->stats.free_count,
- pmap->stats.active_count,
- pmap->stats.inactive_count,
- pmap->stats.wire_count);
-
- printf(" zero_fill_count %d; reactiveations %d; "
- "pageins %d; pageouts %d; faults %d\n",
- pmap->stats.zero_fill_count,
- pmap->stats.reactivations,
- pmap->stats.pageins,
- pmap->stats.pageouts,
- pmap->stats.fault);
-
- printf(" cow_faults %d, lookups %d, hits %d\n",
- pmap->stats.cow_faults,
- pmap->stats.loopups,
- pmap->stats.faults);
-#endif
-
- sdtp = (sdt_entry_t *) pmap->sdt_vaddr; /* addr of physical table */
- sdtv = sdtp + SDT_ENTRIES; /* shadow table with virt address */
- if (sdtp == (sdt_entry_t *)0)
- printf("Error in pmap - sdt_paddr is null.\n");
- else {
- int count = 0;
- printf(" Segment table at 0x%x (0x%x):\n",
- (unsigned)sdtp, (unsigned)sdtv);
- for (i = 0; i < SDT_ENTRIES; i++, sdtp++, sdtv++) {
- if ((sdtp->table_addr != 0 ) || (sdtv->table_addr != 0)) {
- if (count != 0)
- printf("sdt entry %d skip !!\n", count);
- count = 0;
- printf(" (%x)phys: ", i);
- PRINT_SDT(sdtp);
- printf(" (%x)virt: ", i);
- PRINT_SDT(sdtv);
- }
- else
- count++;
- }
- if (count != 0)
- printf("sdt entry %d skip !!\n", count);
- }
-
-} /* pmap_print() */
-
-/*
- * Routine: PMAP_PRINT_TRACE
- *
- * Function:
- * Using virt addr, derive phys addr, printing pmap tables along the way.
- *
- * Parameters:
- * pmap pointer to pmap strucuture
- * va virtual address whose translation is to be trace
- * long_format flag indicating long from output is desired
- *
- * Special Assumptions:
- * No locking required.
- *
- * This function chases down through the translation tree as
- * appropriate for the given virtual address. each table entry
- * encoutered is printed. If the long_format is desired, all entries of
- * each table are printed, with special indication of the entries used in
- * the translation.
- */
-void pmap_print_trace (
- pmap_t pmap,
- vm_offset_t va,
- boolean_t long_format)
-{
- sdt_entry_t *sdtp; /* ptr to sdt table of physical addresses */
- sdt_entry_t *sdtv; /* ptr to sdt shadow table of virtual addresses */
- pt_entry_t *ptep; /* ptr to pte table of physical page addresses */
-
- int i; /* table loop index */
- unsigned long prev_entry; /* keep track of value of previous table entry */
- int n_dup_entries; /* count contiguous duplicate entries */
-
- printf("Trace of virtual address 0x%08x. Pmap @ 0x%08x.\n",
- va, (unsigned)pmap);
-
- /*** SDT TABLES ***/
- /* get addrs of sdt tables */
- sdtp = (sdt_entry_t *)pmap->sdt_vaddr;
- sdtv = sdtp + SDT_ENTRIES;
-
- if (sdtp == SDT_ENTRY_NULL) {
- printf(" Segment table pointer (pmap.sdt_paddr) null, trace stops.\n");
- return;
- }
-
- n_dup_entries = 0;
- prev_entry = 0xFFFFFFFF;
-
- if (long_format) {
- printf(" Segment table at 0x%08x (virt shadow at 0x%08x)\n",
- (unsigned)sdtp, (unsigned)sdtv);
- for (i = 0; i < SDT_ENTRIES; i++, sdtp++, sdtv++) {
- if (prev_entry == ((sdt_entry_template_t *)sdtp)->bits
- && SDTIDX(va) != i && i != SDT_ENTRIES-1) {
- n_dup_entries++;
- continue; /* suppress duplicate entry */
- }
- if (n_dup_entries != 0) {
- printf(" - %d duplicate entries skipped -\n",n_dup_entries);
- n_dup_entries = 0;
- }
- prev_entry = ((pte_template_t *)sdtp)->bits;
- if (SDTIDX(va) == i) {
- printf(" >> (%x)phys: ", i);
- } else {
- printf(" (%x)phys: ", i);
- }
- PRINT_SDT(sdtp);
- if (SDTIDX(va) == i) {
- printf(" >> (%x)virt: ", i);
- } else {
- printf(" (%x)virt: ", i);
- }
- PRINT_SDT(sdtv);
- } /* for */
- } else {
- /* index into both tables for given VA */
- sdtp += SDTIDX(va);
- sdtv += SDTIDX(va);
- printf(" SDT entry index 0x%x at 0x%x (virt shadow at 0x%x)\n",
- SDTIDX(va), (unsigned)sdtp, (unsigned)sdtv);
- printf(" phys: ");
- PRINT_SDT(sdtp);
- printf(" virt: ");
- PRINT_SDT(sdtv);
- }
-
- /*** PTE TABLES ***/
- /* get addrs of page (pte) table (no shadow table) */
-
- sdtp = ((sdt_entry_t *)pmap->sdt_vaddr) + SDTIDX(va);
- #ifdef DBG
- printf("*** DEBUG (sdtp) ");
- PRINT_SDT(sdtp);
- #endif
- sdtv = sdtp + SDT_ENTRIES;
- ptep = (pt_entry_t *)(M88K_PTOB(sdtv->table_addr));
- if (sdtp->dtype != DT_VALID) {
- printf(" segment table entry invlid, trace stops.\n");
- return;
- }
-
- n_dup_entries = 0;
- prev_entry = 0xFFFFFFFF;
- if (long_format) {
- printf(" page table (ptes) at 0x%x\n", (unsigned)ptep);
- for (i = 0; i < PDT_ENTRIES; i++, ptep++) {
- if (prev_entry == ((pte_template_t *)ptep)->bits
- && PDTIDX(va) != i && i != PDT_ENTRIES-1) {
- n_dup_entries++;
- continue; /* suppress suplicate entry */
- }
- if (n_dup_entries != 0) {
- printf(" - %d duplicate entries skipped -\n",n_dup_entries);
- n_dup_entries = 0;
- }
- prev_entry = ((pte_template_t *)ptep)->bits;
- if (PDTIDX(va) == i) {
- printf(" >> (%x)pte: ", i);
- } else {
- printf(" (%x)pte: ", i);
- }
- PRINT_PDT(ptep);
- } /* for */
- } else {
- /* index into page table */
- ptep += PDTIDX(va);
- printf(" pte index 0x%x\n", PDTIDX(va));
- printf(" pte: ");
- PRINT_PDT(ptep);
- }
-} /* pmap_print_trace() */
-
-/*
- * Check whether the current transaction being looked at by dodexc()
- * could have been the one that caused a fault. Given the virtual
- * address, map, and transaction type, checks whether the page at that
- * address is valid, and, for write transactions, whether it has write
- * permission.
- */
-boolean_t pmap_check_transaction(
- pmap_t pmap,
- vm_offset_t va,
- vm_prot_t type)
-{
- pt_entry_t *pte;
- sdt_entry_t *sdt;
- int spl;
-
- PMAP_LOCK(pmap, spl);
-
- if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL) {
- PMAP_UNLOCK(pmap, spl);
- return FALSE;
- }
-
- if (!PDT_VALID(pte)) {
- PMAP_UNLOCK(pmap, spl);
- return FALSE;
- }
-
- /*
- * Valid pte. If the transaction was a read, there is no way it
- * could have been a fault, so return true. For now, assume
- * that a write transaction could have caused a fault. We need
- * to check pte and sdt entries for write permission to really
- * tell.
- */
-
- if (type == VM_PROT_READ) {
- PMAP_UNLOCK(pmap, spl);
- return TRUE;
- } else {
- sdt = SDTENT(pmap,va);
- if (sdt->prot || pte->prot) {
- PMAP_UNLOCK(pmap, spl);
- return FALSE;
- } else {
- PMAP_UNLOCK(pmap, spl);
- return TRUE;
- }
- }
-}
-
-/* New functions to satisfy rpd - contributed by danner */
-
-void pmap_virtual_space(
- vm_offset_t *startp,
- vm_offset_t *endp)
-{
- *startp = virtual_avail;
- *endp = virtual_end;
-}
-
-unsigned int pmap_free_pages(void)
-{
- return atop(avail_end - avail_next);
-}
-
-boolean_t pmap_next_page(vm_offset_t *addrp)
-{
- if (avail_next == avail_end)
- return FALSE;
-
- *addrp = avail_next;
- avail_next += PAGE_SIZE;
- return TRUE;
-}
-
-#if 0
-#ifdef OMRON_PMAP
-/*
- * Set BATC
- */
-void pmap_set_batc(
- pmap_t pmap,
- boolean_t data,
- int i,
- vm_offset_t va,
- vm_offset_t pa,
- boolean_t super,
- boolean_t wt,
- boolean_t global,
- boolean_t ci,
- boolean_t wp,
- boolean_t valid)
-{
- register batc_template_t batctmp;
-
- if (i < 0 || i > (BATC_MAX - 1)) {
- panic("pmap_set_batc: illegal batc number\n");
- /* bad number */
- return;
- }
-
- batctmp.field.lba = va >> 19;
- batctmp.field.pba = pa >> 19;
- batctmp.field.sup = super;
- batctmp.field.wt = wt;
- batctmp.field.g = global;
- batctmp.field.ci = ci;
- batctmp.field.wp = wp;
- batctmp.field.v = valid;
-
- if (data) {
- pmap->d_batc[i].bits = batctmp.bits;
- } else {
- pmap->i_batc[i].bits = batctmp.bits;
- }
-}
-
-void use_batc(
- task_t task,
- boolean_t data, /* for data-cmmu ? */
- int i, /* batc number */
- vm_offset_t va, /* virtual address */
- vm_offset_t pa, /* physical address */
- boolean_t s, /* for super-mode ? */
- boolean_t wt, /* is writethrough */
- boolean_t g, /* is global ? */
- boolean_t ci, /* is cache inhibited ? */
- boolean_t wp, /* is write-protected ? */
- boolean_t v) /* is valid ? */
-{
- pmap_t pmap;
- pmap = vm_map_pmap(task->map);
- pmap_set_batc(pmap, data, i, va, pa, s, wt, g, ci, wp, v);
-}
-
-#endif
-#endif /* 0 */
-#ifdef notyet
-/*
- * Machine-level page attributes
- *
- * The only attribute that may be controlled right now is cacheability.
- *
- * Obviously these attributes will be used in a sparse
- * fashion, so we use a simple sorted list of address ranges
- * which possess the attribute.
- */
-
-/*
- * Destroy an attribute list.
- */
-void pmap_destroy_ranges(pmap_range_t *ranges)
-{
- register pmap_range_t this, next;
-
- this = *ranges;
- while (this != 0) {
- next = this->next;
- pmap_range_free(this);
- this = next;
- }
- *ranges = 0;
-}
-
-/*
- * Lookup an address in a sorted range list.
- */
-boolean_t pmap_range_lookup(
- pmap_range_t *ranges,
- vm_offset_t address)
-{
- register pmap_range_t range;
-
- for (range = *ranges; range != 0; range = range->next) {
- if (address < range->start)
- return FALSE;
- if (address < range->end)
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * Add a range to a list.
- * The pmap must be locked.
- */
-void pmap_range_add(
- pmap_range_t *ranges,
- vm_offset_t start,
- vm_offset_t end)
-{
- register pmap_range_t range, *prev;
-
- /* look for the start address */
-
- for (prev = ranges; (range = *prev) != 0; prev = &range->next) {
- if (start < range->start)
- break;
- if (start <= range->end)
- goto start_overlaps;
- }
-
- /* start address is not present */
-
- if ((range == 0) || (end < range->start)) {
- /* no overlap; allocate a new range */
-
- range = pmap_range_alloc();
- range->start = start;
- range->end = end;
- range->next = *prev;
- *prev = range;
- return;
- }
-
- /* extend existing range forward to start */
-
- range->start = start;
-
- start_overlaps:
- assert((range->start <= start) && (start <= range->end));
-
- /* delete redundant ranges */
-
- while ((range->next != 0) && (range->next->start <= end)) {
- pmap_range_t old;
-
- old = range->next;
- range->next = old->next;
- range->end = old->end;
- pmap_range_free(old);
- }
-
- /* extend existing range backward to end */
-
- if (range->end < end)
- range->end = end;
-}
-
-/*
- * Remove a range from a list.
- * The pmap must be locked.
- */
-void pmap_range_remove(
- pmap_range_t *ranges,
- vm_offset_t start,
- vm_offset_t end)
-{
- register pmap_range_t range, *prev;
-
- /* look for start address */
-
- for (prev = ranges; (range = *prev) != 0; prev = &range->next) {
- if (start <= range->start)
- break;
- if (start < range->end) {
- if (end < range->end) {
- pmap_range_t new;
-
- /* split this range */
-
- new = pmap_range_alloc();
- new->next = range->next;
- new->start = end;
- new->end = range->end;
-
- range->next = new;
- range->end = start;
- return;
- }
-
- /* truncate this range */
-
- range->end = start;
- }
- }
-
- /* start address is not in the middle of a range */
-
- while ((range != 0) && (range->end <= end)) {
- *prev = range->next;
- pmap_range_free(range);
- range = *prev;
- }
-
- if ((range != 0) && (range->start < end))
- range->start = end;
-}
-#endif /* notyet */
diff --git a/sys/arch/mvme88k/m88k/process.S b/sys/arch/mvme88k/m88k/process.S
deleted file mode 100644
index 9369cc63e80..00000000000
--- a/sys/arch/mvme88k/m88k/process.S
+++ /dev/null
@@ -1,270 +0,0 @@
-#ifndef ASSEMBLER /* predefined by ascpp, at least */
-#define ASSEMBLER
-#endif
-
-#include "machine/locore.h"
-#include "machine/asm.h"
-#include "assym.s"
-
-#ifndef NBPG
-#define NBPG 4096
-#endif /* NBPG */
-
- data
- align 4
-Lsw0:
- string "cpu_switch\n"
- align 4
-swchanpanic:
- string "switch wchan\n"
- align 4
-swsrunpanic:
- string "switch SRUN\n"
-
- text
- align 8
-Lswchanpanic:
- or.u r2, r0, hi16(swchanpanic)
- or r2, r2, lo16(swchanpanic)
- bsr _panic
-
-Lswsrunpanic:
- or.u r2, r0, hi16(swsrunpanic)
- or r2, r2, lo16(swsrunpanic)
- bsr _panic
-/*
- * At exit of a process, do a cpu_switch for the last time.
- * The mapping of the pcb at p->p_addr has already been deleted,
- * and the memory for the pcb+stack has been freed.
- * The ipl is high enough to prevent the memory from being reallocated.
- */
-ENTRY(switch_exit)
- /*
- * Change pcb to idle u. area, i.e., set r31 to top of stack
- * and set curpcb to point to _idle_u.
- */
- or.u r31, r0, hi16(_idle_u)
- or r31, r31,lo16(_idle_u)
- or.u r10, r10,hi16(_curpcb)
- or r10, r10,lo16(_curpcb)
- st r31, r0, r10 /* curpcb = &idle_u */
- addu r31, r31, UPAGES * NBPG /* now on idle_u stack */
- or.u r10, r0, hi16(_curproc)
- st r0, r10, lo16(_curproc) /* curproc = NULL */
- bsr.n _cpu_switch
- or r2, r0, r10
-
-/*
- * When no processes are on the runq, switch
- * idles here watiing for something to come ready.
- */
-LABEL(idle)
- or.u r10, r0, hi16(_curproc)
- st r0, r10, lo16(_curproc) /* curproc = NULL */
-
- or r2,r0,0
- bsr _spln /*(void) spl0(); */
- ; spin reading _whichqs until nonzero
-1:
- or.u r10, r0, hi16(_whichqs)
- ld r11, r10,lo16(_whichqs)
- bcnd eq0, r11, 1b
- bsr.n _spln
- or r2,r0,6
- br Lsw1
-/*
- * cpu_switch()
- * XXX - Arg 1 is a proc pointer (curproc) but this doesn't use it.
- * XXX - how about using stack for saving spl and last proc?
- */
-ENTRY(cpu_switch)
- or.u r10, r0, hi16(_curpcb)
- ld r10,r10, lo16(_curpcb)
- st r1, r10, 0 ; save r1 in pcb
- bsr _spl
- or.u r10, r0, hi16(_curpcb) ; a call can clobber
- ld r10,r10, lo16(_curpcb) ; r10 - so reload it
- st r2, r10, 19 * 4 ; save ipl in pcb
- or.u r11, r0, hi16(_curproc)
- ld r11,r11, lo16(_curproc)
- or.u r12, r0, hi16(_lastproc)
- or r12, r12, lo16(_lastproc)
- st r11, r12, 0 ; lastproc = curproc
- or.u r11, r0, hi16(_curproc)
- st r0, r11, lo16(_curproc) ; curproc = NULL
- bsr.n _spln
- or r2,r0,6
-Lsw1:
- /*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- or r6, r0, r0
- or.u r7, r0, hi16(_whichqs)
- ld r7, r7, lo16(_whichqs)
-Lswchk:
- bcnd eq0, r7, idle
- ff1 r6, r7 ; 0 <= r6 <= 31
-
- or.u r7, r0, hi16(_qs)
- or r7, r7, lo16(_qs)
- mak r6, r6, 0<3>
- lda r8, r7[r6] ; r8 = qs[ff1(whichqs)]
- ; r8 is q, r9 is p
- ld r9, r8, P_FORW ; p = q->p_forw
- ld r12, r9, P_FORW ; r12 is p->p_forw
- st r12, r8, P_FORW ; q->p_forw = p->p_forw
- st r12, r8, 0 ; q = p->p_forw
- ld r12, r9, P_BACK ; r12 is p->p_back
- st r12, r8, P_BACK ; q->p_back = p->p_back
- lda r8, r7[r6] ; reload r8 with qs[ff1(whichqs)]
- ld r12, r8, P_FORW; q->p_forw
- cmp r12, r12, r8 ; q == q->p_forw; anyone left on queue?
- bb1 ne, r12, Lsw2 ; no, skip
- ext r6, r6, 0<3>
- add r6, r6, 1 ; turn off the bit we looked at
- or.u r7, r0, hi16(_whichqs)
- ld r8, r7, lo16(_whichqs)
- and.c r8, r8, r6 ; whichqs &= ~the bit
- st r8, r7, lo16(_whichqs) ; reset bit in whichqs
-Lsw2:
- ld r2, r9, P_WCHAN
- bcnd ne0, r2, Lswchanpanic
- ld.b r2, r9, P_STAT
- cmp r2, r2, SRUN
- bb1 ne, r2, Lswsrunpanic
-
- or.u r11, r0, hi16(_want_resched)
- st r0, r11, lo16(_want_resched)
-
- or.u r11, r0, hi16(_curproc)
- st r9, r11,lo16(_curproc) ; curproc = p
-
- or.u r2, r0, hi16(_lastproc)
- ld r2, r2, lo16(_lastproc)
-
- or.u r10, r0, hi16(_curpcb)
- ld r10,r10, lo16(_curpcb)
-
- cmp r2, r2, r9
- bb1 eq, r2, Lswsameproc
-
- /*
- * Save state of previous process in its pcb.
- */
-
- ; r1 and ipl already saved above
- st r14,r10,4
- st r15,r10,2*4
- st r16,r10,3*4
- st r17,r10,4*4
- st r18,r10,5*4
- st r19,r10,6*4
- st r20,r10,7*4
- st r21,r10,8*4
- st r22,r10,9*4
- st r23,r10,10*4
- st r24,r10,11*4
- st r25,r10,12*4
- st r26,r10,13*4
- st r27,r10,14*4
- st r28,r10,15*4
- st r29,r10,16*4
- st r30,r10,17*4 /* save frame pointer */
- st r31,r10,18*4 /* save stack pointer */
- /* ipl already saved */
- ; r9 is curproc
- or.u r10, r0, hi16(_curpcb)
- or r10,r10, lo16(_curpcb)
- st r0, r9, P_BACK ; p->p_back = 0
- ld r3, r9, P_ADDR
- st r3, r10, 0 ; curpcb = p->p_addr
- /* see if pmap_activate needs to be called */
- ld r2, r9, P_VMSPACE ; vmspace = p->p_vmspace
- addu r2, r2, VM_PMAP ; pmap = &vmspace.vm_pmap
-#if 0
- ld r5, r2, PM_STCHG ; pmap->st_changed?
- bcnd eq0, r5, Lswnochg ; no, skip
-#endif
- or r14, r0, r9 ; save p in r14
- bsr _pmap_activate ; pmap_activate(pmap, pcb)
- or r9, r0, r14 ; restore p saved in r14
-
-Lswnochg:
- or.u r31, r0, hi16(_intstack_end)
- or r31,r31, lo16(_intstack_end); now goto a tmp stack for NMI
- bsr.n _load_u_area ; load_u_area(p)
- or r2, r0, r9
- or.u r10, r0, hi16(_curpcb)
- ld r10, r10, lo16(_curpcb)
- ; XXX Is this correct/necessary?
- st r10, r14, P_ADDR ; p->p_addr = curpcb; restore p_addr
- ; flush some data cache here
-
- ; restore from the current context
-
- ld r1,r10,0
- ld r14,r10,4
- ld r15,r10,2*4
- ld r16,r10,3*4
- ld r17,r10,4*4
- ld r18,r10,5*4
- ld r19,r10,6*4
- ld r20,r10,7*4
- ld r21,r10,8*4
- ld r22,r10,9*4
- ld r23,r10,10*4
- ld r24,r10,11*4
- ld r25,r10,12*4
- ld r26,r10,13*4
- ld r27,r10,14*4
- ld r28,r10,15*4
- ld r29,r10,16*4
- ld r30,r10,17*4 /* restore frame pointer */
- ld r31,r10,18*4 /* restore stack pointer */
-Lswsameproc:
- ld r2, r10,19*4 /* restore interrupt mask */
- subu r31,r31,40
- st r1, r31,32 ; save r1 on stack
- bsr _spln
-Lcxswdone:
- ld r1, r31,32 ; restore r1 from stack
- addu r31,r31,40
- jmp.n r1
- or r2, r0, 1 ; return 1 (for alternate returns)
-
-/*
- * savectx(pcb)
- * Update pcb, saving current processor state.
- */
-ENTRY(savectx)
- /* get the spl mask */
- subu r31,r31,40 /* allocate stack for r1 and args */
- st r1,r31,36 /* save return address */
- st r2,r31,32 /* save r2 */
- bsr _spl /* get the current interrupt mask */
- ld r1,r31,36 /* recover return address */
- ld r10,r31,32 /* recover r2 into r10 */
- addu r31,r31,40 /* put stack pointer back */
- st r1,r10,0 /* do setjmp */ /* save return address */
- st r14,r10,4
- st r15,r10,2*4
- st r16,r10,3*4
- st r17,r10,4*4
- st r18,r10,5*4
- st r19,r10,6*4
- st r20,r10,7*4
- st r21,r10,8*4
- st r22,r10,9*4
- st r23,r10,10*4
- st r24,r10,11*4
- st r25,r10,12*4
- st r26,r10,13*4
- st r27,r10,14*4
- st r28,r10,15*4
- st r29,r10,16*4
- st r30,r10,17*4 /* save frame pointer */
- st r31,r10,18*4 /* save stack pointer */
- st r2, r10,19*4 /* save interrupt mask */
- jmp.n r1
- or r2,r0,r0
diff --git a/sys/arch/mvme88k/m88k/process_machdep.c b/sys/arch/mvme88k/m88k/process_machdep.c
deleted file mode 100644
index 62a3ba89dfb..00000000000
--- a/sys/arch/mvme88k/m88k/process_machdep.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $NetBSD: process_machdep.c,v 1.5 1994/11/20 20:54:37 deraadt Exp $ */
-
-/*
- * 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
- */
-
-/*
- * 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 <machine/psl.h>
-#include <machine/reg.h>
-#if 0
-#include <machine/frame.h>
-#endif
-#include <sys/ptrace.h>
-
-int
-process_read_regs(p, regs)
- struct proc *p;
- struct reg *regs;
-{
-#if 0
- /* NOTE: struct reg == struct trapframe */
- bcopy(p->p_md.md_tf, (caddr_t)regs, sizeof(struct reg));
-#endif
- return (0);
-}
-
-int
-process_write_regs(p, regs)
- struct proc *p;
- struct reg *regs;
-{
-#if 0
- int psr = p->p_md.md_tf->tf_psr & ~PSR_ICC;
- bcopy((caddr_t)regs, p->p_md.md_tf, sizeof(struct reg));
- p->p_md.md_tf->tf_psr = psr | (regs->r_psr & PSR_ICC);
-#endif
- return (0);
-}
-
-int
-process_sstep(p, sstep)
- struct proc *p;
-{
-#if 0
- if (sstep)
- return EINVAL;
-#endif
- return (0);
-}
-
-int
-process_set_pc(p, addr)
- struct proc *p;
- caddr_t addr;
-{
-#if 0
- p->p_md.md_tf->tf_pc = (u_int)addr;
- p->p_md.md_tf->tf_npc = (u_int)addr + 4;
-#endif
- return (0);
-}
-
-int
-process_read_fpregs(p, regs)
-struct proc *p;
-struct fpreg *regs;
-{
-#if 0
- extern struct fpstate initfpstate;
- struct fpstate *statep = &initfpstate;
-
- /* NOTE: struct fpreg == struct fpstate */
- if (p->p_md.md_fpstate)
- statep = p->p_md.md_fpstate;
- bcopy(statep, regs, sizeof(struct fpreg));
-#endif
- return 0;
-}
-
-int
-process_write_fpregs(p, regs)
-struct proc *p;
-struct fpreg *regs;
-{
-#if 0
- if (p->p_md.md_fpstate == NULL)
- return EINVAL;
-
- bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg));
-#endif
- return 0;
-}
diff --git a/sys/arch/mvme88k/m88k/swapgeneric.c b/sys/arch/mvme88k/m88k/swapgeneric.c
deleted file mode 100644
index b0db1cf7830..00000000000
--- a/sys/arch/mvme88k/m88k/swapgeneric.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 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.
- *
- * @(#)swapgeneric.c 7.5 (Berkeley) 5/7/91
- * $Id: swapgeneric.c,v 1.1 1995/10/18 10:54:27 deraadt Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/reboot.h>
-#include <sys/device.h>
-#include <sys/disklabel.h>
-#include <sys/fcntl.h> /* XXXX and all that uses it */
-#include <sys/proc.h> /* XXXX and all that uses it */
-#include <sys/disk.h>
-
-#include "sd.h"
-#include "cd.h"
-
-/*
- * Only boot on ufs. (XXX?)
- */
-int ffs_mountroot();
-int (*mountroot)() = ffs_mountroot;
-
-/*
- * Generic configuration; all in one
- */
-dev_t rootdev = NODEV;
-dev_t dumpdev = NODEV;
-
-struct swdevt swdevt[] = {
- { NODEV, 1, 0 },
- { NODEV, 0, 0 },
-};
-
-#if NSD > 0
-extern struct cfdriver sdcd;
-#endif
-#if NCD > 0
-extern struct cfdriver cdcd;
-#endif
-
-struct genericconf {
- struct cfdriver *gc_driver;
- dev_t gc_root;
-};
-
-/*
- * the system will assign rootdev to the first partition 'a'
- * found with FS_BSDFFS fstype. so these should be ordered
- * in prefernece of boot. however it does walk units backwards
- * to remain compatible with the old amiga method of picking
- * the last root found.
- */
-struct genericconf genericconf[] = {
-#if NSD > 0
- {&sdcd, makedev(4, 0)},
-#endif
-#if NCD > 0
- {&cdcd, makedev(6, 0)},
-#endif
- { 0 },
-};
-
-struct genericconf *
-getgenconf(bp)
- char *bp;
-{
- char *cp;
- struct genericconf *gc;
-
- for (;;) {
- printf("root device> ");
- gets(bp);
- for (gc = genericconf; gc->gc_driver; gc++)
- if (gc->gc_driver->cd_name[0] == bp[0] &&
- gc->gc_driver->cd_name[1] == bp[1])
- break;
- if (gc->gc_driver == NULL) {
- printf("use one of:");
- for (gc = genericconf; gc->gc_driver; gc++)
- printf(" %s%%d", gc->gc_driver->cd_name);
- printf("\n");
- continue;
- }
- cp = bp + 2;
- if (*cp >= '0' && *cp <= '9')
- break;
- printf("bad/missing unit number\n");
- }
- return(gc);
-}
-
-setconf()
-{
- struct dkdevice *dkp;
- struct partition *pp;
- struct genericconf *gc;
- struct bdevsw *bdp;
- int unit, swaponroot;
- char name[128];
- char *cp;
-
- swaponroot = 0;
-
- if (rootdev != NODEV)
- goto justdoswap;
-
- unit = 0;
- if (boothowto & RB_ASKNAME) {
- gc = getgenconf(name);
- cp = name + 2;
- while (*cp >= '0' && *cp <= '9')
- unit = 10 * unit + *cp++ - '0';
- if (*cp == '*')
- swaponroot = 1;
- unit &= 0x7;
- goto found;
- }
- for (gc = genericconf; gc->gc_driver; gc++) {
- for (unit = gc->gc_driver->cd_ndevs - 1; unit >= 0; unit--) {
- if (gc->gc_driver->cd_devs[unit] == NULL)
- continue;
- /*
- * this is a hack these drivers should use
- * dk_dev and not another instance directly above.
- */
- dkp = (struct dkdevice *)
- ((struct device *)gc->gc_driver->cd_devs[unit] + 1);
- if (dkp->dk_driver == NULL ||
- dkp->dk_driver->d_strategy == NULL)
- continue;
- for (bdp = bdevsw; bdp < (bdevsw + nblkdev); bdp++)
- if (bdp->d_strategy ==
- dkp->dk_driver->d_strategy)
- break;
- if (bdp->d_open(MAKEDISKDEV(major(gc->gc_root),
- unit, 0), FREAD | FNONBLOCK, 0, curproc))
- continue;
- bdp->d_close(MAKEDISKDEV(major(gc->gc_root), unit,
- 0), FREAD | FNONBLOCK, 0, curproc);
- pp = &dkp->dk_label.d_partitions[0];
- if (pp->p_size == 0 || pp->p_fstype != FS_BSDFFS)
- continue;
- goto found;
- }
- }
- printf("no suitable root\n");
- asm("or r9,r0,0x0063");
- asm("tb0 0,r0,0x1f0");
- /*NOTREACHED*/
-found:
-
- gc->gc_root = MAKEDISKDEV(major(gc->gc_root), unit, 0);
- rootdev = gc->gc_root;
-
-justdoswap:
- swdevt[0].sw_dev = MAKEDISKDEV(major(rootdev),
- DISKUNIT(rootdev), 1);
- /*
- swdevt[0].sw_dev = dumpdev = MAKEDISKDEV(major(rootdev),
- DISKUNIT(rootdev), 1);
- */
- /* swap size and dumplo set during autoconfigure */
- if (swaponroot)
- rootdev = swdevt[0].sw_dev;
-}
-
-gets(cp)
- char *cp;
-{
- register char *lp;
- register c;
-
- lp = cp;
- for (;;) {
- cnputc(c = cngetc());
- switch (c) {
- case '\n':
- case '\r':
- *lp = 0;
- return;
- case '\b':
- case '\177':
- if (lp > cp) {
- lp--;
- cnputc(' ');
- cnputc('\b');
- }
- continue;
- case '#':
- lp--;
- if (lp < cp)
- lp = cp;
- continue;
- case '@':
- case 'u'&037:
- lp = cp;
- cnputc('\n');
- continue;
- default:
- *lp++ = c;
- }
- }
-}
diff --git a/sys/arch/mvme88k/m88k/syscall.stub b/sys/arch/mvme88k/m88k/syscall.stub
deleted file mode 100644
index 4a1055556d1..00000000000
--- a/sys/arch/mvme88k/m88k/syscall.stub
+++ /dev/null
@@ -1,29 +0,0 @@
- /*
- * system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
- * or r13, r0, <code>
- * tb0 0, r0, <128> <- xip
- * br err <- nip
- * jmp r1 <- fip
- * err: or.u r3, r0, hi16(errno)
- * st r2, r3, lo16(errno)
- * subu r2, r0, 1
- * jmp r1
- *
- * So, when we take syscall trap, sxip/snip/sfip will be as
- * shown above.
- * Given this,
- * 1. If the system call returned 0, need to skip nip.
- * nip = fip, fip += 4
- * (doesn't matter what fip + 4 will be but we will never
- * execute this since jmp r1 at nip will change the execution flow.)
- * 2. If the system call returned an errno > 0, plug the value
- * in r2, and leave nip and fip unchanged. This will have us
- * executing "br err" on return to user space.
- * 3. If the system call code returned ERESTART or EJUSTRETURN,
- * we need to rexecute the trap instruction. Back up the pipe
- * line.
- * fip = nip, nip = xip
- */
diff --git a/sys/arch/mvme88k/m88k/timerreg.h b/sys/arch/mvme88k/m88k/timerreg.h
deleted file mode 100644
index 3bafa844c02..00000000000
--- a/sys/arch/mvme88k/m88k/timerreg.h
+++ /dev/null
@@ -1,8 +0,0 @@
-struct ticktimer {
- u_int ttcmpreg; /* Timer compare register */
- u_int ttcounter; /* Timer counter */
- u_int tticr; /* Timer control register */
-};
-
-struct timers {
-};
diff --git a/sys/arch/mvme88k/m88k/trap.c b/sys/arch/mvme88k/m88k/trap.c
deleted file mode 100644
index ebdf5288c81..00000000000
--- a/sys/arch/mvme88k/m88k/trap.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * 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.
- */
-
-#include <sys/types.h>
-#include <vm/vm.h>
-#include <vm/vm_kern.h> /* kernel_map */
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/syscall.h>
-#include <sys/ktrace.h>
-#include <machine/cpu.h> /* DMT_VALID, etc. */
-#include <machine/m88100.h> /* DMT_VALID, etc. */
-#include <machine/trap.h>
-#include <machine/psl.h> /* FIP_E, etc. */
-
-#include <sys/systm.h>
-
-#if (DDB)
-#include <machine/db_machdep.h>
-#endif /* DDB */
-
-int stop_on_user_memory_error = 0;
-
-#define TRAPTRACE
-#if defined(TRAPTRACE)
-unsigned traptrace = 0;
-#endif
-
-#if DDB
-#define DEBUG_MSG db_printf
-#else
-#define DEBUG_MSG printf
-#endif /* DDB */
-
-#ifdef JEFF_DEBUG
-# undef DEBUG_MSG
-# define DEBUG_MSG raw_printf
-#endif
-
-#define USERMODE(PSR) (((struct psr*)&(PSR))->psr_mode == 0)
-#define SYSTEMMODE(PSR) (((struct psr*)&(PSR))->psr_mode != 0)
-
-/* XXX MAJOR CLEANUP REQUIRED TO PORT TO BSD */
-
-char *trap_type[] = {
- "Reset",
- "Interrupt Exception",
- "Instruction Access",
- "Data Access Exception",
- "Misaligned Access",
- "Unimplemented Opcode",
- "Privileg Violation",
- "Bounds Check Violation",
- "Illegal Integer Divide",
- "Integer Overflow",
- "Error Exception",
-};
-
-int trap_types = sizeof trap_type / sizeof trap_type[0];
-
-static inline void
-userret(struct proc *p, struct m88100_saved_state *frame, u_quad_t oticks)
-{
- int sig;
-
- /* take pending signals */
- while ((sig = CURSIG(p)) != 0)
- postsig(sig);
- p->p_priority = p->p_usrpri;
-
- if (want_ast) {
- want_ast = 0;
- if (p->p_flag & P_OWEUPC) {
- p->p_flag &= ~P_OWEUPC;
- ADDUPROF(p);
- }
- }
-
- if (want_resched) {
- /*
- * Since we are curproc, clock will normally just change
- * our priority without moving us from one queue to another
- * (since the running process is not on a queue.)
- * If that happened after we put ourselves on the run queue
- * but before we switched, we might not be on the queue
- * indicated by our priority.
- */
- (void) splstatclock();
- setrunqueue(p);
- p->p_stats->p_ru.ru_nivcsw++;
- mi_switch();
- (void) spl0();
- while ((sig = CURSIG(p)) != 0)
- postsig(sig);
- }
-
- /*
- * If profiling, charge recent system time to the trapped pc.
- */
- if (p->p_flag & P_PROFIL)
- addupc_task(p, frame->sxip & ~3,
- (int)(p->p_sticks - oticks));
-
- curpriority = p->p_priority;
-}
-
-void
-panictrap(int type, struct m88100_saved_state *frame)
-{
- static int panicing = 0;
- if (panicing++ == 0) {
- printf("trap type %d, v = %x, frame %x\n", type, frame->sxip & ~3, frame);
- regdump(frame);
- }
- if ((u_int)type < trap_types)
- panic(trap_type[type]);
- panic("trap");
- /*NOTREACHED*/
-}
-
-/*ARGSUSED*/
-void
-trap(unsigned type, struct m88100_saved_state *frame)
-{
- struct proc *p;
- u_quad_t sticks = 0;
- vm_map_t map;
- vm_offset_t va;
- vm_prot_t ftype;
- unsigned nss, fault_addr;
- struct vmspace *vm;
- int result;
- int sig = 0;
-
- extern vm_map_t kernel_map;
- extern int fubail(), subail();
-
- cnt.v_trap++;
- if ((p = curproc) == NULL)
- p = &proc0;
-
- if (USERMODE(frame->epsr)) {
- sticks = p->p_sticks;
- type += T_USER;
- p->p_md.md_tf = frame; /* for ptrace/signals */
- }
-
- switch(type)
- {
- default:
- panictrap(frame->vector, frame);
- /*NOTREACHED*/
-
-#if defined(DDB)
- case T_KDB_BREAK:
- /*FALLTHRU*/
- case T_KDB_BREAK+T_USER:
- {
- int s = db_splhigh();
- db_enable_interrupt(); /* turn interrupts on */
- ddb_break_trap(T_KDB_BREAK,(db_regs_t*)frame);
- db_disable_interrupt(); /* shut them back off */
- db_splx(s);
- return;
- }
- case T_KDB_ENTRY:
- /*FALLTHRU*/
- case T_KDB_ENTRY+T_USER:
- {
- int s = db_splhigh();
- db_enable_interrupt(); /* turn interrupts on */
- ddb_entry_trap(T_KDB_ENTRY,(db_regs_t*)frame);
- db_disable_interrupt(); /* shut them back off */
- db_splx(s);
- return;
- }
-
-#if 0
- case T_ILLFLT:
- {
- int s = db_splhigh();
- db_enable_interrupt(); /* turn interrupts on */
- ddb_error_trap(type == T_ILLFLT ? "unimplemented opcode" :
- "error fault", (db_regs_t*)frame);
- db_disable_interrupt(); /* shut them back off */
- db_splx(s);
- return;
- }
-#endif /* 0 */
-#endif /* DDB */
-
- case T_MISALGNFLT:
- DEBUG_MSG("kernel misalgined "
- "access exception @ 0x%08x\n", frame->sxip);
- panictrap(frame->vector, frame);
- break;
-
- case T_INSTFLT:
- /* kernel mode instruction access fault */
- /* XXX I think this should be illegal, but not sure. Will leave
- * the way it is for now. Should never,never happen for a non-paged
- * kernel
- */
- /*FALLTHRU*/
- case T_DATAFLT:
- /* kernel mode data fault */
- /*
- * if the faulting address is in user space, handle it in
- * the context of the user process. Else, use kernel map.
- */
-
- if (type == T_DATAFLT) {
- fault_addr = frame->dma0;
- if (frame->dmt0 & (DMT_WRITE|DMT_LOCKBAR))
- ftype = VM_PROT_READ|VM_PROT_WRITE;
- else
- ftype = VM_PROT_READ;
- } else {
- fault_addr = frame->sxip & XIP_ADDR;
- ftype = VM_PROT_READ;
- }
-
- va = trunc_page((vm_offset_t)fault_addr);
-
- vm = p->p_vmspace;
- map = &vm->vm_map;
-
- /* if instruction fault or data fault on a kernel address... */
- if ((type == T_INSTFLT) || (frame->dmt0 & DMT_DAS))
- map = kernel_map;
-
- /*
- * We don't want to call vm_fault() if it is fuwintr() or
- * suwintr(). These routines are for copying from interrupt
- * context and vm_fault() can potentially sleep.
- */
-
- if (p->p_addr->u_pcb.pcb_onfault == (int)fubail ||
- p->p_addr->u_pcb.pcb_onfault == (int)subail)
- goto outtahere;
-
- result = vm_fault(map, va, ftype, FALSE);
-
- if (result == KERN_SUCCESS) {
- /*
- * We could resolve the fault. Call data_access_emulation
- * to drain the data unit pipe line and reset dmt0 so that
- * trap won't get called again. For inst faults, back up
- * the pipe line.
- */
- if (type == T_DATAFLT) {
- data_access_emulation(frame);
- frame->dmt0 = 0;
- } else {
- frame->sfip = frame->snip & ~FIP_E;
- frame->snip = frame->sxip & ~NIP_E;
- }
- return;
- }
-
- /* XXX Is this right? */
- if (type == T_DATAFLT && (frame->dmt0 & DMT_DAS) == 0)
- goto user_fault;
-
- /*
- * if still the fault is not resolved ...
- */
- if (!p->p_addr->u_pcb.pcb_onfault)
- panictrap(frame->vector, frame);
-
- outtahere:
- frame->snip = ((unsigned)p->p_addr->u_pcb.pcb_onfault ) | FIP_V;
- frame->sfip = ((unsigned)p->p_addr->u_pcb.pcb_onfault + 4) | FIP_V;
- frame->sxip = 0;
- frame->dmt0 = 0; /* XXX what about other trans. in data unit */
- return;
-
- case T_INSTFLT+T_USER:
- /* User mode instruction access fault */
- /*FALLTHRU*/
- case T_DATAFLT+T_USER:
- user_fault:
- sig = SIGILL;
- if (type == T_INSTFLT+T_USER)
- fault_addr = frame->sxip & XIP_ADDR;
- else
- fault_addr = frame->dma0;
- if (frame->dmt0 & (DMT_WRITE|DMT_LOCKBAR))
- ftype = VM_PROT_READ|VM_PROT_WRITE;
- else
- ftype = VM_PROT_READ;
-
- va = trunc_page((vm_offset_t)fault_addr);
-
- vm = p->p_vmspace;
- map = &vm->vm_map;
-
- result = vm_fault(map, va, ftype, FALSE);
-
- if ((caddr_t)va >= vm->vm_maxsaddr) {
- if (result == KERN_SUCCESS) {
- nss = clrnd(USRSTACK - va);/* XXX check this */
- if (nss > vm->vm_ssize)
- vm->vm_ssize = nss;
- } else if (result == KERN_PROTECTION_FAILURE)
- result = KERN_INVALID_ADDRESS;
- }
-
- if (result == KERN_SUCCESS) {
- if (type == T_DATAFLT+T_USER) {
- /*
- * We could resolve the fault. Call
- * data_access_emulation to drain the data unit
- * pipe line and reset dmt0 so that trap won't
- * get called again.
- */
- data_access_emulation(frame);
- frame->dmt0 = 0;
- } else {
- /* back up SXIP, SNIP clearing the the Error bit */
- frame->sfip = frame->snip & ~FIP_E;
- frame->snip = frame->sxip & ~NIP_E;
- }
- } else {
- sig = result == KERN_PROTECTION_FAILURE ? SIGBUS : SIGSEGV;
- }
-
- break;
-
- case T_MISALGNFLT+T_USER:
- sig = SIGBUS;
- break;
-
- case T_PRIVINFLT+T_USER:
- case T_ILLFLT+T_USER:
- sig = SIGILL;
- break;
-
- case T_BNDFLT+T_USER:
- case T_ZERODIV+T_USER:
- case T_OVFFLT+T_USER:
- sig = SIGBUS;
- break;
-
- case T_FPEPFLT+T_USER:
- case T_FPEIFLT+T_USER:
- sig = SIGFPE;
- break;
-
- case T_ASTFLT+T_USER:
- want_ast = 0;
- (void) spl0();
- if (ssir & SIR_NET) {
- siroff(SIR_NET);
- cnt.v_soft++;
- netintr();
- }
- if (ssir & SIR_CLOCK) {
- siroff(SIR_CLOCK);
- cnt.v_soft++;
- /* XXXX softclock(&frame.f_stackadj); */
- softclock();
- }
- if (p->p_flag & P_OWEUPC) {
- p->p_flag &= ~P_OWEUPC;
- ADDUPROF(p);
- }
- break;
-
- case T_SIGTRAP+T_USER:
- break;
-
- case T_STEPBPT+T_USER:
- /*
- * This trap is used by the kernel to support single-step
- * debugging (although any user could generate this trap
- * which should probably be handled differently). When a
- * process is continued by a debugger with the PT_STEP
- * function of ptrace (single step), the kernel inserts
- * one or two breakpoints in the user process so that only
- * one instruction (or two in the case of a delayed branch)
- * is executed. When this breakpoint is hit, we get the
- * T_STEPBPT trap.
- */
- frame->sfip = frame->snip; /* set up next FIP */
- frame->snip = frame->sxip; /* set up next NIP */
- break;
-
- case T_USERBPT+T_USER:
- /*
- * This trap is meant to be used by debuggers to implement
- * breakpoint debugging. When we get this trap, we just
- * return a signal which gets caught by the debugger.
- */
-
- frame->sfip = frame->snip; /* set up the next FIP */
- frame->snip = frame->sxip; /* set up the next NIP */
- break;
-
- }
-
- /*
- * If trap from supervisor mode, just return
- */
- if (SYSTEMMODE(frame->epsr))
- return;
-
- if (sig) {
- trapsignal(p, sig, frame->vector);
- /*
- * don't want multiple faults - we are going to
- * deliver signal.
- */
- frame->dmt0 = 0;
- }
-
- userret(p, frame, sticks);
-}
-
-void error_fault(struct m88100_saved_state *frame)
-{
- DEBUG_MSG("\n[ERROR FAULT (Bad News[tm]) frame 0x%08x]\n", frame);
-#if DDB
- gimmeabreak();
- DEBUG_MSG("[you really can't restart after an error fault.]\n");
- gimmeabreak();
-#endif /* DDB */
-}
-
-syscall(u_int code, struct m88100_saved_state *tf)
-{
- register int i, nsys, *ap, nap;
- register struct sysent *callp;
- register struct proc *p;
- int error, new;
- struct args {
- int i[8];
- } args;
- int rval[2];
- u_quad_t sticks;
- extern struct pcb *curpcb;
-
- cnt.v_syscall++;
-
- callp = p->p_emul->e_sysent;
- nsys = p->p_emul->e_nsysent;
-
- p = curproc;
-#ifdef DIAGNOSTIC
- if (USERMODE(tf->epsr) == 0)
- panic("syscall");
- if (curpcb != &p->p_addr->u_pcb)
- panic("syscall curpcb/ppcb");
- if (tf != (struct trapframe *)((caddr_t)curpcb))
- panic("syscall trapframe");
-#endif
-
- sticks = p->p_sticks;
- p->p_md.md_tf = tf;
-
- /*
- * For 88k, all the arguments are passed in the registers (r2-r12)
- * For syscall (and __syscall), r2 (and r3) has the actual code.
- * __syscall takes a quad syscall number, so that other
- * arguments are at their natural alignments.
- */
- ap = &tf->r[2];
- nap = 6;
-
- switch (code) {
- case SYS_syscall:
- code = *ap++;
- nap--;
- break;
- case SYS___syscall:
- if (callp != sysent)
- break;
- code = ap[_QUAD_LOWWORD];
- ap += 2;
- nap -= 2;
- break;
- }
-
- /* Callp currently points to syscall, which returns ENOSYS. */
-
- if (code < 0 || code >= nsys)
- callp += p->p_emul->e_nosys;
- else {
- callp += code;
- i = callp->sy_narg;
- if (i > 8)
- panic("syscall nargs");
- /*
- * just copy them; syscall stub made sure all the
- * args are moved from user stack to registers.
- */
- bcopy((caddr_t)ap, (caddr_t)args.i, i * 4);
- }
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSCALL))
- ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
-#endif
- rval[0] = 0;
- rval[1] = 0; /* doesn't seem to be used any where */
- error = (*callp->sy_call)(p, &args, rval);
- /*
- * system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
- * or r13, r0, <code>
- * tb0 0, r0, <128> <- xip
- * br err <- nip
- * jmp r1 <- fip
- * err: or.u r3, r0, hi16(errno)
- * st r2, r3, lo16(errno)
- * subu r2, r0, 1
- * jmp r1
- *
- * So, when we take syscall trap, sxip/snip/sfip will be as
- * shown above.
- * Given this,
- * 1. If the system call returned 0, need to skip nip.
- * nip = fip, fip += 4
- * (doesn't matter what fip + 4 will be but we will never
- * execute this since jmp r1 at nip will change the execution flow.)
- * 2. If the system call returned an errno > 0, plug the value
- * in r2, and leave nip and fip unchanged. This will have us
- * executing "br err" on return to user space.
- * 3. If the system call code returned ERESTART or EJUSTRETURN,
- * we need to rexecute the trap instruction. Back up the pipe
- * line.
- * fip = nip, nip = xip
- */
-
- if (error == 0) {
- /*
- * If fork succeeded and we are the child, our stack
- * has moved and the pointer tf is no longer valid,
- * and p is wrong. Compute the new trapframe pointer.
- * (The trap frame invariably resides at the
- * tippity-top of the u. area.)
- */
- p = curproc;
- tf = USER_REGS(p);
- tf->r[2] = 0;
- tf->epsr &= ~PSR_C;
- tf->snip = tf->sfip & ~3;
- tf->sfip = tf->snip + 4;
- } else if (error > 0 /*error != ERESTART && error != EJUSTRETURN*/) {
-bad:
- tf->r[2] = error;
- tf->epsr |= PSR_C; /* fail */
- tf->snip = tf->snip & ~3;
- tf->sfip = tf->sfip & ~3;
- } else {
- /* if (error == ERESTART || error == EJUSTRETURN)
- back up the pipe line */
- tf->sfip = tf->snip & ~3;
- tf->snip = tf->sxip & ~3;
- }
- userret(p, tf, sticks);
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p->p_tracep, code, error, rval[0]);
-#endif
-}
-
-#if MACH_PCSAMPLE > 0
-#include "mach_pcsample.h"
-/*
- * return saved state for interrupted user thread
- */
-unsigned interrupted_pc(p)
-proc *p;
-{
- struct m88100_saved_state *frame = &p->pcb->user_state;
- unsigned sxip = frame->sxip;
- unsigned PC = sxip & ~3; /* clear lower bits which are flags... */
- return PC;
-}
-#endif /* MACH_PCSAMPLE > 0*/
diff --git a/sys/arch/mvme88k/m88k/vm_machdep.c b/sys/arch/mvme88k/m88k/vm_machdep.c
deleted file mode 100644
index f7bc68de766..00000000000
--- a/sys/arch/mvme88k/m88k/vm_machdep.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 1993 Adam Glass
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1982, 1986, 1990 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.
- *
- * 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: vm_machdep.c 1.21 91/04/06$
- * from: @(#)vm_machdep.c 7.10 (Berkeley) 5/7/91
- * vm_machdep.c,v 1.3 1993/07/07 07:09:32 cgd Exp
- * $Id: vm_machdep.c,v 1.1 1995/10/18 10:54:27 deraadt Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/user.h>
-#include <sys/vnode.h>
-
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_map.h>
-
-#include <machine/cpu.h>
-
-/*
- * Finish a fork operation, with process p2 nearly set up.
- * Copy and update the kernel stack and pcb, making the child
- * ready to run, and marking it so that it can return differently
- * than the parent. Returns 1 in the child process, 0 in the parent.
- * We currently double-map the user area so that the stack is at the same
- * address in each process; in the future we will probably relocate
- * the frame pointers on the stack after copying.
- */
-cpu_fork(struct proc *p1, struct proc *p2)
-{
- register struct user *up = p2->p_addr;
- int off, ssz;
- caddr_t sp;
- extern caddr_t getsp();
- extern char kstack[];
-
- p2->p_md.md_tf = p1->p_md.md_tf;
-
- /*
- * Copy pcb and stack from proc p1 to p2.
- * We do this as cheaply as possible, copying only the active
- * part of the stack. The stack and pcb need to agree;
- * this is tricky, as the final pcb is constructed by savectx,
- * but its frame isn't yet on the stack when the stack is copied.
- * cpu_switch compensates for this when the child eventually runs.
- * This should be done differently, with a single call
- * that copies and updates the pcb+stack,
- * replacing the bcopy and savectx.
- */
- p2->p_addr->u_pcb = p1->p_addr->u_pcb;
- sp = getsp();
- ssz = (unsigned int)UADDR + UPAGES * NBPG - (unsigned int)sp;
- off = (unsigned int)sp - (unsigned int)UADDR;
-#if 0
- bcopy((caddr_t)(UADDR + off), (caddr_t)((unsigned int)p2->p_addr + off),
- ssz);
-#endif /* 0 */
- /* copy from UADDR to p2 */
- memcpy((caddr_t)((unsigned int)p2->p_addr + off),
- (caddr_t)(UADDR + off), ssz);
- save_u_area(p2, p2->p_addr);
- PMAP_ACTIVATE(&p2->p_vmspace->vm_pmap, &up->u_pcb, 0);
-
- /*
- * Arrange for a non-local goto when the new process
- * is started, to resume here, returning nonzero from setjmp.
- */
- if (savectx(up, 1)) {
- /*
- * Return 1 in child.
- */
- return (1);
- }
- return (0);
-}
-
-/*
- * cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * including the memory for the user structure and kernel stack.
- * Once finished, we call switch_exit, which switches to a temporary
- * pcb and stack and never returns. We block memory allocation
- * until switch_exit has made things safe again.
- */
-volatile void
-cpu_exit(struct proc *p)
-{
- extern volatile void switch_exit();
- vmspace_free(p->p_vmspace);
-
- (void) splimp();
- kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES));
- switch_exit(p);
- /* NOTREACHED */
-}
-
-int
-cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred)
-{
-
- return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES),
- (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL,
- p));
-}
-
-/*
- * Finish a swapin operation.
- * We neded to update the cached PTEs for the user area in the
- * machine dependent part of the proc structure.
- */
-
-void
-cpu_swapin(struct proc *p)
-{
- save_u_area(p, (vm_offset_t)p->p_addr);
-}
-
-extern vm_map_t phys_map;
-
-/*
- * Map an IO request into kernel virtual address space. Requests fall into
- * one of five catagories:
- *
- * B_PHYS|B_UAREA: User u-area swap.
- * Address is relative to start of u-area (p_addr).
- * B_PHYS|B_PAGET: User page table swap.
- * Address is a kernel VA in usrpt (Usrptmap).
- * B_PHYS|B_DIRTY: Dirty page push.
- * Address is a VA in proc2's address space.
- * B_PHYS|B_PGIN: Kernel pagein of user pages.
- * Address is VA in user's address space.
- * B_PHYS: User "raw" IO request.
- * Address is VA in user's address space.
- *
- * All requests are (re)mapped into kernel VA space via the useriomap
- * (a name with only slightly more meaning than "kernelmap")
- *
- * XXX we allocate KVA space by using kmem_alloc_wait which we know
- * allocates space without backing physical memory. This implementation
- * is a total crock, the multiple mappings of these physical pages should
- * be reflected in the higher-level VM structures to avoid problems.
- */
-void
-vmapbuf(struct buf *bp)
-{
- register int npf;
- register caddr_t addr;
- register long flags = bp->b_flags;
- struct proc *p;
- int off;
- vm_offset_t kva;
- register vm_offset_t pa;
-
- if ((flags & B_PHYS) == 0)
- panic("vmapbuf");
- addr = bp->b_saveaddr = bp->b_data;
- off = (int)addr & PGOFSET;
- p = bp->b_proc;
- npf = btoc(round_page(bp->b_bcount + off));
-
- /*
- * Why phys_map? kernelmap should be OK - after all, the
- * we are mapping user va to kernel va or remapping some
- * kernel va to another kernel va. XXX -nivas
- */
-
- kva = kmem_alloc_wait(phys_map, ctob(npf));
- bp->b_data = (caddr_t) (kva + off);
- while (npf--) {
- pa = pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),
- (vm_offset_t)addr);
- if (pa == 0)
- panic("vmapbuf: null page frame");
- pmap_enter(vm_map_pmap(phys_map), kva, trunc_page(pa),
- VM_PROT_READ|VM_PROT_WRITE, TRUE);
- addr += PAGE_SIZE;
- kva += PAGE_SIZE;
- }
-}
-
-/*
- * Free the io map PTEs associated with this IO operation.
- * We also invalidate the TLB entries and restore the original b_addr.
- */
-void
-vunmapbuf(struct buf *bp)
-{
- register caddr_t addr;
- register int npf;
- vm_offset_t kva;
-
- if ((bp->b_flags & B_PHYS) == 0)
- panic("vunmapbuf");
- addr = bp->b_data;
- npf = btoc(round_page(bp->b_bcount + ((int)addr & PGOFSET)));
- kva = (vm_offset_t)((int)addr & ~PGOFSET);
- kmem_free_wakeup(phys_map, kva, ctob(npf));
- bp->b_data = bp->b_saveaddr;
- bp->b_saveaddr = NULL;
-}
-
-caddr_t
-obio_vm_alloc(int npages)
-{
- vm_size_t size;
- vm_offset_t addr;
- int result;
-
- if (npages == 0);
- size = npages*NBPG;
- addr = vm_map_min(phys_map);
- result = vm_map_find(phys_map, NULL, (vm_offset_t) 0, &addr, size, TRUE);
- if (result != KERN_SUCCESS) return NULL;
- vm_map_lock(phys_map);
- vm_map_delete(phys_map, addr, addr+size);
- vm_map_unlock(phys_map);
- return (caddr_t) addr;
-}
-
-/*
- * Move pages from one kernel virtual address to another.
- * Both addresses are assumed to reside in the Sysmap,
- * and size must be a multiple of CLSIZE.
- */
-void
-pagemove(caddr_t from, caddr_t to, int size)
-{
- register vm_offset_t pa;
-
-#ifdef DEBUG
- if (size & CLOFSET)
- panic("pagemove");
-#endif
- while (size > 0) {
- pa = pmap_extract(kernel_pmap, (vm_offset_t)from);
-#ifdef DEBUG
- if (pa == 0)
- panic("pagemove 2");
- if (pmap_extract(kernel_pmap, (vm_offset_t)to) != 0)
- panic("pagemove 3");
-#endif
- pmap_remove(kernel_pmap,
- (vm_offset_t)from, (vm_offset_t)from + NBPG);
- pmap_enter(kernel_pmap,
- (vm_offset_t)to, pa, VM_PROT_READ|VM_PROT_WRITE, 1);
- from += NBPG;
- to += NBPG;
- size -= NBPG;
- }
-}