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