summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2007-12-14 23:03:48 +0000
committermarcel <marcel@FreeBSD.org>2007-12-14 23:03:48 +0000
commite1d637468a8e50a52b36e23719afcb2d27cd3d05 (patch)
treef6158482f1dcb0dda5cbe1919374b2f89b1ca1a4
parentc8b672d408760215d85c007ea7936a5662824469 (diff)
downloadFreeBSD-src-e1d637468a8e50a52b36e23719afcb2d27cd3d05.zip
FreeBSD-src-e1d637468a8e50a52b36e23719afcb2d27cd3d05.tar.gz
This file was repocopied to src/sys/powerpc/aim, where it will
live on -- an afterlife.
-rw-r--r--sys/powerpc/powerpc/clock.c318
-rw-r--r--sys/powerpc/powerpc/copyinout.c356
-rw-r--r--sys/powerpc/powerpc/interrupt.c101
-rw-r--r--sys/powerpc/powerpc/locore.S208
-rw-r--r--sys/powerpc/powerpc/machdep.c995
-rw-r--r--sys/powerpc/powerpc/mmu_oea.c2544
-rw-r--r--sys/powerpc/powerpc/nexus.c487
-rw-r--r--sys/powerpc/powerpc/ofw_machdep.c436
-rw-r--r--sys/powerpc/powerpc/ofwmagic.S75
-rw-r--r--sys/powerpc/powerpc/swtch.S158
-rw-r--r--sys/powerpc/powerpc/trap.c681
-rw-r--r--sys/powerpc/powerpc/trap_subr.S540
-rw-r--r--sys/powerpc/powerpc/uio_machdep.c124
-rw-r--r--sys/powerpc/powerpc/uma_machdep.c91
-rw-r--r--sys/powerpc/powerpc/vm_machdep.c369
15 files changed, 0 insertions, 7483 deletions
diff --git a/sys/powerpc/powerpc/clock.c b/sys/powerpc/powerpc/clock.c
deleted file mode 100644
index 0c01cf0..0000000
--- a/sys/powerpc/powerpc/clock.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- *
- * $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $
- */
-/*
- * Copyright (C) 2001 Benno Rice.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/bus.h>
-#include <sys/clock.h>
-#include <sys/timetc.h>
-#include <sys/interrupt.h>
-
-#include <dev/ofw/openfirm.h>
-
-#include <machine/clock.h>
-#include <machine/cpu.h>
-#include <machine/intr.h>
-#include <machine/md_var.h>
-
-/*
- * Initially we assume a processor with a bus frequency of 12.5 MHz.
- */
-u_int tickspending;
-u_long ns_per_tick = 80;
-static u_long ticks_per_sec = 12500000;
-static long ticks_per_intr;
-static volatile u_long lasttb;
-
-#define DIFF19041970 2082844800
-
-static int clockinitted = 0;
-
-static timecounter_get_t decr_get_timecount;
-
-static struct timecounter decr_timecounter = {
- decr_get_timecount, /* get_timecount */
- 0, /* no poll_pps */
- ~0u, /* counter_mask */
- 0, /* frequency */
- "decrementer" /* name */
-};
-
-void
-inittodr(time_t base)
-{
- time_t deltat;
- u_int rtc_time;
- struct timespec ts;
- phandle_t phandle;
- ihandle_t ihandle;
- char rtcpath[128];
- u_int rtcsecs;
-
- /*
- * If we can't read from RTC, use the fs time.
- */
- phandle = OF_finddevice("rtc");
- if (phandle != -1) {
- OF_package_to_path(phandle, rtcpath, sizeof(rtcpath));
- ihandle = OF_open(rtcpath);
- if (ihandle != -1) {
- if (OF_call_method("read-rtc", ihandle,
- 0, 1, &rtcsecs))
- printf("RTC call method error\n");
- else {
- ts.tv_sec = rtcsecs - DIFF19041970;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- return;
- }
- }
- }
-
- {
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- return;
- }
- clockinitted = 1;
- ts.tv_sec = rtc_time - DIFF19041970;
-
- deltat = ts.tv_sec - base;
- if (deltat < 0) {
- deltat = -deltat;
- }
- if (deltat < 2 * SECDAY) {
- tc_setclock(&ts);
- return;
- }
-
- printf("WARNING: clock %s %d days",
- ts.tv_sec < base ? "lost" : "gained", (int)(deltat / SECDAY));
-
- printf(" -- CHECK AND RESET THE DATE!\n");
-}
-
-/*
- * Similar to the above
- */
-void
-resettodr()
-{
-
-}
-
-void
-decr_intr(struct trapframe *frame)
-{
- u_long tb;
- long tick;
- int nticks;
-
- /*
- * Check whether we are initialized.
- */
- if (!ticks_per_intr)
- return;
-
- /*
- * Based on the actual time delay since the last decrementer reload,
- * we arrange for earlier interrupt next time.
- */
- __asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(tick));
- for (nticks = 0; tick < 0; nticks++)
- tick += ticks_per_intr;
- mtdec(tick);
- /*
- * lasttb is used during microtime. Set it to the virtual
- * start of this tick interval.
- */
- lasttb = tb + tick - ticks_per_intr;
-
- nticks += tickspending;
- tickspending = 0;
-
- /*
- * Reenable interrupts
- */
-#if 0
- msr = mfmsr();
- mtmsr(msr | PSL_EE | PSL_RI);
-#endif
- /*
- * Do standard timer interrupt stuff.
- * Do softclock stuff only on the last iteration.
- */
-#if 0
- while (--nticks > 0) {
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
- }
-#endif
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-}
-
-void
-decr_init(void)
-{
- int qhandle, phandle;
- char name[32];
- unsigned int msr;
-
- phandle = 0;
-
- /*
- * Get this info during autoconf? XXX
- */
- for (qhandle = OF_peer(0); qhandle; qhandle = phandle) {
- if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0
- && !strcmp(name, "cpu")
- && OF_getprop(qhandle, "timebase-frequency",
- &ticks_per_sec, sizeof ticks_per_sec) >= 0) {
- /*
- * Should check for correct CPU here? XXX
- */
- msr = mfmsr();
- mtmsr(msr & ~(PSL_EE|PSL_RI));
-
- ns_per_tick = 1000000000 / ticks_per_sec;
- ticks_per_intr = ticks_per_sec / hz;
- __asm __volatile ("mftb %0" : "=r"(lasttb));
- mtdec(ticks_per_intr);
-
- mtmsr(msr);
-
- break;
- }
- if ((phandle = OF_child(qhandle)))
- continue;
- while (qhandle) {
- if ((phandle = OF_peer(qhandle)))
- break;
- qhandle = OF_parent(qhandle);
- }
- }
- if (!phandle)
- panic("no cpu node");
-}
-
-void
-decr_tc_init(void)
-{
- decr_timecounter.tc_frequency = ticks_per_sec;
- tc_init(&decr_timecounter);
-}
-
-static __inline u_quad_t
-mftb(void)
-{
- u_long scratch;
- u_quad_t tb;
-
- __asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b"
- : "=r"(tb), "=r"(scratch));
- return tb;
-}
-
-static unsigned
-decr_get_timecount(struct timecounter *tc)
-{
- return mftb();
-}
-
-/*
- * Wait for about n microseconds (at least!).
- */
-void
-DELAY(int n)
-{
- u_quad_t tb, ttb;
-
- tb = mftb();
- ttb = tb + (n * 1000 + ns_per_tick - 1) / ns_per_tick;
- while (tb < ttb)
- tb = mftb();
-}
-
-/*
- * Nothing to do.
- */
-void
-cpu_startprofclock(void)
-{
-
- /* Do nothing */
-}
-
-void
-cpu_stopprofclock(void)
-{
-}
-
-/*
- * XXX Needed by syscons
- */
-int
-sysbeep(int pitch, int period)
-{
-
- return (0);
-}
diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
deleted file mode 100644
index 4e9f777..0000000
--- a/sys/powerpc/powerpc/copyinout.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*-
- * Copyright (C) 2002 Benno Rice
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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.
-*/
-/*-
- * Copyright (C) 1993 Wolfgang Solfrank.
- * Copyright (C) 1993 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_map.h>
-
-#include <machine/pcb.h>
-#include <machine/sr.h>
-
-int setfault(faultbuf); /* defined in locore.S */
-
-/*
- * Makes sure that the right segment of userspace is mapped in.
- */
-static __inline void
-set_user_sr(register_t vsid)
-{
-
- isync();
- __asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
- isync();
-}
-
-int
-copyout(const void *kaddr, void *udaddr, size_t len)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- const char *kp;
- char *up, *p;
- size_t l;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (EFAULT);
- }
-
- kp = kaddr;
- up = udaddr;
-
- while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
-
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
-
- set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
-
- bcopy(kp, p, l);
-
- up += l;
- kp += l;
- len -= l;
- }
-
- td->td_pcb->pcb_onfault = NULL;
- return (0);
-}
-
-int
-copyin(const void *udaddr, void *kaddr, size_t len)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- const char *up;
- char *kp, *p;
- size_t l;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (EFAULT);
- }
-
- kp = kaddr;
- up = udaddr;
-
- while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
-
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
-
- set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
-
- bcopy(p, kp, l);
-
- up += l;
- kp += l;
- len -= l;
- }
-
- td->td_pcb->pcb_onfault = NULL;
- return (0);
-}
-
-int
-copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- const char *up;
- char *kp;
- size_t l;
- int rv, c;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (EFAULT);
- }
-
- kp = kaddr;
- up = udaddr;
-
- rv = ENAMETOOLONG;
-
- for (l = 0; len-- > 0; l++) {
- if ((c = fubyte(up++)) < 0) {
- rv = EFAULT;
- break;
- }
-
- if (!(*kp++ = c)) {
- l++;
- rv = 0;
- break;
- }
- }
-
- if (done != NULL) {
- *done = l;
- }
-
- td->td_pcb->pcb_onfault = NULL;
- return (rv);
-}
-
-int
-subyte(void *addr, int byte)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- char *p;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (-1);
- }
-
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
-
- *p = (char)byte;
-
- td->td_pcb->pcb_onfault = NULL;
- return (0);
-}
-
-int
-suword(void *addr, long word)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- long *p;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (-1);
- }
-
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
-
- *p = word;
-
- td->td_pcb->pcb_onfault = NULL;
- return (0);
-}
-
-int
-suword32(void *addr, int32_t word)
-{
- return (suword(addr, (long)word));
-}
-
-
-int
-fubyte(const void *addr)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- u_char *p;
- int val;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (-1);
- }
-
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
-
- val = *p;
-
- td->td_pcb->pcb_onfault = NULL;
- return (val);
-}
-
-long
-fuword(const void *addr)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- long *p, val;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (-1);
- }
-
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
-
- val = *p;
-
- td->td_pcb->pcb_onfault = NULL;
- return (val);
-}
-
-int32_t
-fuword32(const void *addr)
-{
- return ((int32_t)fuword(addr));
-}
-
-uint32_t
-casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
-{
- return (casuword((volatile u_long *)base, oldval, newval));
-}
-
-u_long
-casuword(volatile u_long *addr, u_long old, u_long new)
-{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
- u_long *p, val;
-
- td = PCPU_GET(curthread);
- pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
-
- set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (-1);
- }
-
- val = *p;
- (void) atomic_cmpset_32((volatile uint32_t *)p, old, new);
-
- td->td_pcb->pcb_onfault = NULL;
-
- return (val);
-}
diff --git a/sys/powerpc/powerpc/interrupt.c b/sys/powerpc/powerpc/interrupt.c
deleted file mode 100644
index ff77fc8..0000000
--- a/sys/powerpc/powerpc/interrupt.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*-
- * Copyright 2002 by Peter Grehan. 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. 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.
- *
- * $FreeBSD$
- */
-
-/*
- * Interrupts are dispatched to here from locore asm
- */
-
-#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/interrupt.h>
-#include <sys/kernel.h>
-#include <sys/kthread.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/smp.h>
-#include <sys/unistd.h>
-#include <sys/vmmeter.h>
-
-#include <machine/cpu.h>
-#include <machine/clock.h>
-#include <machine/db_machdep.h>
-#include <machine/fpu.h>
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <machine/md_var.h>
-#include <machine/pcb.h>
-#include <machine/psl.h>
-#include <machine/trap.h>
-#include <machine/spr.h>
-#include <machine/sr.h>
-
-#include "pic_if.h"
-
-/*
- * A very short dispatch, to try and maximise assembler code use
- * between all exception types. Maybe 'true' interrupts should go
- * here, and the trap code can come in separately
- */
-void
-powerpc_interrupt(struct trapframe *framep)
-{
- struct thread *td;
- register_t ee;
-
- td = curthread;
-
- switch (framep->exc) {
- case EXC_EXI:
- atomic_add_int(&td->td_intr_nesting_level, 1);
- PIC_DISPATCH(pic, framep);
- atomic_subtract_int(&td->td_intr_nesting_level, 1);
- break;
-
- case EXC_DECR:
- atomic_add_int(&td->td_intr_nesting_level, 1);
- decr_intr(framep);
- atomic_subtract_int(&td->td_intr_nesting_level, 1);
- break;
-
- default:
- /* Re-enable interrupts if applicable. */
- ee = framep->srr1 & PSL_EE;
- if (ee != 0) {
- mtmsr(mfmsr() | ee);
- isync();
- }
- trap(framep);
- }
-}
diff --git a/sys/powerpc/powerpc/locore.S b/sys/powerpc/powerpc/locore.S
deleted file mode 100644
index 1a3c0bb..0000000
--- a/sys/powerpc/powerpc/locore.S
+++ /dev/null
@@ -1,208 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
-
-/*-
- * Copyright (C) 2001 Benno Rice
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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.
- */
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "assym.s"
-
-#include <sys/syscall.h>
-
-#include <machine/trap.h>
-#include <machine/param.h>
-#include <machine/sr.h>
-#include <machine/spr.h>
-#include <machine/psl.h>
-#include <machine/asm.h>
-
-/* Locate the per-CPU data structure */
-#define GET_CPUINFO(r) \
- mfsprg0 r
-
-/*
- * Globals
- */
- .data
-GLOBAL(tmpstk)
- .space 8208
-GLOBAL(esym)
- .long 0 /* end of symbol table */
-
-GLOBAL(ofmsr)
- .long 0, 0, 0, 0, 0 /* msr/sprg0-3 used in Open Firmware */
-
-GLOBAL(powersave)
- .long 0
-
-#define INTSTK 16384 /* 16K interrupt stack */
-#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */
-GLOBAL(intrnames)
- .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2
-GLOBAL(eintrnames)
- .align 4
-GLOBAL(intrcnt)
- .space INTRCNT_COUNT * 4 * 2
-GLOBAL(eintrcnt)
-
-/*
- * File-scope for locore.S
- */
-idle_u:
- .long 0 /* fake uarea during idle after exit */
-openfirmware_entry:
- .long 0 /* Open Firmware entry point */
-srsave:
- .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
-/*
- * This symbol is here for the benefit of kvm_mkdb, and is supposed to
- * mark the start of kernel text.
- */
- .text
- .globl kernel_text
-kernel_text:
-
-/*
- * Startup entry. Note, this must be the first thing in the text
- * segment!
- */
- .text
- .globl __start
-__start:
-#ifdef FIRMWORKSBUGS
- mfmsr 0
- andi. 0,0,PSL_IR|PSL_DR
- beq 1f
-
- bl ofwr_init
-1:
-#endif
- li 8,0
- li 9,0x100
- mtctr 9
-1:
- dcbf 0,8
- icbi 0,8
- addi 8,8,0x20
- bdnz 1b
- sync
- isync
-
- /* Save the argument pointer and length */
- mr 20,6
- mr 21,7
-
- lis 8,openfirmware_entry@ha
- stw 5,openfirmware_entry@l(8) /* save client interface handler */
- mr 3,5
-
- lis 1,tmpstk@ha
- addi 1,1,tmpstk@l
- addi 1,1,8192
-
- mfmsr 0
- lis 9,ofmsr@ha
- stwu 0,ofmsr@l(9)
-
- mfsprg0 0 /* save SPRG0-3 */
- stw 0,4(9) /* ofmsr[1] = sprg0 */
- mfsprg1 0
- stw 0,8(9) /* ofmsr[2] = sprg1 */
- mfsprg2 0
- stw 0,12(9) /* ofmsr[3] = sprg2 */
- mfsprg3 0
- stw 0,16(9) /* ofmsr[4] = sprg3 */
-
- bl OF_init
-
- lis 4,end@ha
- addi 4,4,end@l
- mr 5,4
-
- lis 3,kernel_text@ha
- addi 3,3,kernel_text@l
-
- /* Restore the argument pointer and length */
- mr 6,20
- mr 7,21
-
- bl powerpc_init
- bl mi_startup
- b OF_exit
-
-/*
- * int setfault()
- *
- * Similar to setjmp to setup for handling faults on accesses to user memory.
- * Any routine using this may only call bcopy, either the form below,
- * or the (currently used) C code optimized, so it doesn't use any non-volatile
- * registers.
- */
- .globl setfault
-setfault:
- mflr 0
- mfcr 12
- mfsprg 4,0
- lwz 4,PC_CURTHREAD(4)
- lwz 4,TD_PCB(4)
- stw 3,PCB_ONFAULT(4)
- stw 0,0(3)
- stw 1,4(3)
- stw 2,8(3)
- stmw 12,12(3)
- xor 3,3,3
- blr
-
-#include <powerpc/powerpc/trap_subr.S>
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
deleted file mode 100644
index 7cea2c0..0000000
--- a/sys/powerpc/powerpc/machdep.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- */
-/*-
- * Copyright (C) 2001 Benno Rice
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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.
- * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_compat.h"
-#include "opt_ddb.h"
-#include "opt_kstack_pages.h"
-#include "opt_msgbuf.h"
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/bus.h>
-#include <sys/cons.h>
-#include <sys/cpu.h>
-#include <sys/eventhandler.h>
-#include <sys/exec.h>
-#include <sys/imgact.h>
-#include <sys/kdb.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/linker.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/msgbuf.h>
-#include <sys/mutex.h>
-#include <sys/ptrace.h>
-#include <sys/reboot.h>
-#include <sys/signalvar.h>
-#include <sys/sysctl.h>
-#include <sys/sysent.h>
-#include <sys/sysproto.h>
-#include <sys/ucontext.h>
-#include <sys/uio.h>
-#include <sys/vmmeter.h>
-#include <sys/vnode.h>
-
-#include <net/netisr.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_pager.h>
-
-#include <machine/bat.h>
-#include <machine/cpu.h>
-#include <machine/elf.h>
-#include <machine/fpu.h>
-#include <machine/md_var.h>
-#include <machine/metadata.h>
-#include <machine/mmuvar.h>
-#include <machine/pcb.h>
-#include <machine/powerpc.h>
-#include <machine/reg.h>
-#include <machine/sigframe.h>
-#include <machine/trap.h>
-#include <machine/vmparam.h>
-
-#include <ddb/ddb.h>
-
-#include <dev/ofw/openfirm.h>
-
-#ifdef DDB
-extern vm_offset_t ksym_start, ksym_end;
-#endif
-
-int cold = 1;
-
-struct pcpu __pcpu[MAXCPU];
-struct trapframe frame0;
-
-vm_offset_t kstack0;
-vm_offset_t kstack0_phys;
-
-char machine[] = "powerpc";
-SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
-
-static int cacheline_size = CACHELINESIZE;
-SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
- CTLFLAG_RD, &cacheline_size, 0, "");
-
-static void cpu_startup(void *);
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
-
-void powerpc_init(u_int, u_int, u_int, void *);
-
-int save_ofw_mapping(void);
-int restore_ofw_mapping(void);
-
-void install_extint(void (*)(void));
-
-int setfault(faultbuf); /* defined in locore.S */
-
-static int grab_mcontext(struct thread *, mcontext_t *, int);
-
-void asm_panic(char *);
-
-long Maxmem = 0;
-long realmem = 0;
-
-struct pmap ofw_pmap;
-extern int ofmsr;
-
-struct bat battable[16];
-
-struct kva_md_info kmi;
-
-void setPQL2(int *const size, int *const ways);
-
-void
-setPQL2(int *const size, int *const ways)
-{
- return;
-}
-
-static void
-powerpc_ofw_shutdown(void *junk, int howto)
-{
- if (howto & RB_HALT) {
- OF_halt();
- }
- OF_reboot();
-}
-
-static void
-cpu_startup(void *dummy)
-{
-
- /*
- * Initialise the decrementer-based clock.
- */
- decr_init();
-
- /*
- * Good {morning,afternoon,evening,night}.
- */
- cpu_setup(PCPU_GET(cpuid));
-
- /* startrtclock(); */
-#ifdef PERFMON
- perfmon_init();
-#endif
- printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
- ptoa(physmem) / 1048576);
- realmem = physmem;
-
- /*
- * Display any holes after the first chunk of extended memory.
- */
- if (bootverbose) {
- int indx;
-
- printf("Physical memory chunk(s):\n");
- for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
- int size1 = phys_avail[indx + 1] - phys_avail[indx];
-
- printf("0x%08x - 0x%08x, %d bytes (%d pages)\n",
- phys_avail[indx], phys_avail[indx + 1] - 1, size1,
- size1 / PAGE_SIZE);
- }
- }
-
- vm_ksubmap_init(&kmi);
-
- printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
- ptoa(cnt.v_free_count) / 1048576);
-
- /*
- * Set up buffers, so they can be used to read disk labels.
- */
- bufinit();
- vm_pager_bufferinit();
-
- EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0,
- SHUTDOWN_PRI_LAST);
-
-#ifdef SMP
- /*
- * OK, enough kmem_alloc/malloc state should be up, lets get on with it!
- */
- mp_start(); /* fire up the secondaries */
- mp_announce();
-#endif /* SMP */
-}
-
-extern char kernel_text[], _end[];
-
-extern void *trapcode, *trapsize;
-extern void *alitrap, *alisize;
-extern void *dsitrap, *dsisize;
-extern void *decrint, *decrsize;
-extern void *extint, *extsize;
-extern void *dblow, *dbsize;
-extern void *vectrap, *vectrapsize;
-
-void
-powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
-{
- struct pcpu *pc;
- vm_offset_t end, off;
- void *kmdp;
- char *env;
-
- end = 0;
- kmdp = NULL;
-
- /*
- * Parse metadata if present and fetch parameters. Must be done
- * before console is inited so cninit gets the right value of
- * boothowto.
- */
- if (mdp != NULL) {
- preload_metadata = mdp;
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp != NULL) {
- boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
- end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
-#ifdef DDB
- ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
- ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
-#endif
- }
- }
-
- /*
- * Init params/tunables that can be overridden by the loader
- */
- init_param1();
-
- /*
- * Start initializing proc0 and thread0.
- */
- proc_linkup0(&proc0, &thread0);
- thread0.td_frame = &frame0;
-
- /*
- * Set up per-cpu data.
- */
- pc = &__pcpu[0];
- pcpu_init(pc, 0, sizeof(struct pcpu));
- pc->pc_curthread = &thread0;
- pc->pc_curpcb = thread0.td_pcb;
- pc->pc_cpuid = 0;
-
- __asm __volatile("mtsprg 0, %0" :: "r"(pc));
-
- mutex_init();
-
- /*
- * Initialize the console before printing anything.
- */
- cninit();
-
- /*
- * Complain if there is no metadata.
- */
- if (mdp == NULL || kmdp == NULL) {
- printf("powerpc_init: no loader metadata.\n");
- }
-
- kdb_init();
-
- kobj_machdep_init();
-
- /*
- * XXX: Initialize the interrupt tables.
- * Disable translation in case the vector area
- * hasn't been mapped (G5)
- */
- mtmsr(mfmsr() & ~(PSL_IR | PSL_DR));
- isync();
- bcopy(&trapcode, (void *)EXC_RST, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_MCHK, (size_t)&trapsize);
- bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
- bcopy(&trapcode, (void *)EXC_ISI, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize);
- bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize);
- bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_FPA, (size_t)&trapsize);
- bcopy(&vectrap, (void *)EXC_VEC, (size_t)&vectrapsize);
- bcopy(&trapcode, (void *)EXC_VECAST, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_THRM, (size_t)&trapsize);
- bcopy(&trapcode, (void *)EXC_BPT, (size_t)&trapsize);
-#ifdef KDB
- bcopy(&dblow, (void *)EXC_RST, (size_t)&dbsize);
- bcopy(&dblow, (void *)EXC_MCHK, (size_t)&dbsize);
- bcopy(&dblow, (void *)EXC_PGM, (size_t)&dbsize);
- bcopy(&dblow, (void *)EXC_TRC, (size_t)&dbsize);
- bcopy(&dblow, (void *)EXC_BPT, (size_t)&dbsize);
-#endif
- __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
-
- /*
- * Make sure translation has been enabled
- */
- mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
- isync();
-
- /*
- * Initialise virtual memory.
- */
- pmap_mmu_install(MMU_TYPE_OEA, 0); /* XXX temporary */
- pmap_bootstrap(startkernel, endkernel);
-
- /*
- * Initialize params/tunables that are derived from memsize
- */
- init_param2(physmem);
-
- /*
- * Grab booted kernel's name
- */
- env = getenv("kernelname");
- if (env != NULL) {
- strlcpy(kernelname, env, sizeof(kernelname));
- freeenv(env);
- }
-
- /*
- * Finish setting up thread0.
- */
- thread0.td_kstack = kstack0;
- thread0.td_pcb = (struct pcb *)
- (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
-
- /*
- * Map and initialise the message buffer.
- */
- for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
- pmap_kenter((vm_offset_t)msgbufp + off, msgbuf_phys + off);
- msgbufinit(msgbufp, MSGBUF_SIZE);
-
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter("Boot flags requested debugger");
-#endif
-}
-
-void
-bzero(void *buf, size_t len)
-{
- caddr_t p;
-
- p = buf;
-
- while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
- *p++ = 0;
- len--;
- }
-
- while (len >= sizeof(u_long) * 8) {
- *(u_long*) p = 0;
- *((u_long*) p + 1) = 0;
- *((u_long*) p + 2) = 0;
- *((u_long*) p + 3) = 0;
- len -= sizeof(u_long) * 8;
- *((u_long*) p + 4) = 0;
- *((u_long*) p + 5) = 0;
- *((u_long*) p + 6) = 0;
- *((u_long*) p + 7) = 0;
- p += sizeof(u_long) * 8;
- }
-
- while (len >= sizeof(u_long)) {
- *(u_long*) p = 0;
- len -= sizeof(u_long);
- p += sizeof(u_long);
- }
-
- while (len) {
- *p++ = 0;
- len--;
- }
-}
-
-void
-sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
-{
- struct trapframe *tf;
- struct sigframe *sfp;
- struct sigacts *psp;
- struct sigframe sf;
- struct thread *td;
- struct proc *p;
- int oonstack, rndfsize;
- int sig;
- int code;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
- sig = ksi->ksi_signo;
- code = ksi->ksi_code;
- psp = p->p_sigacts;
- mtx_assert(&psp->ps_mtx, MA_OWNED);
- tf = td->td_frame;
- oonstack = sigonstack(tf->fixreg[1]);
-
- rndfsize = ((sizeof(sf) + 15) / 16) * 16;
-
- CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
- catcher, sig);
-
- /*
- * Save user context
- */
- memset(&sf, 0, sizeof(sf));
- grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
- sf.sf_uc.uc_sigmask = *mask;
- sf.sf_uc.uc_stack = td->td_sigstk;
- sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
- ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
-
- sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
-
- /*
- * Allocate and validate space for the signal handler context.
- */
- if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sfp = (struct sigframe *)(td->td_sigstk.ss_sp +
- td->td_sigstk.ss_size - rndfsize);
- } else {
- sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
- }
-
- /*
- * Translate the signal if appropriate (Linux emu ?)
- */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
- /*
- * Save the floating-point state, if necessary, then copy it.
- */
- /* XXX */
-
- /*
- * Set up the registers to return to sigcode.
- *
- * r1/sp - sigframe ptr
- * lr - sig function, dispatched to by blrl in trampoline
- * r3 - sig number
- * r4 - SIGINFO ? &siginfo : exception code
- * r5 - user context
- * srr0 - trampoline function addr
- */
- tf->lr = (register_t)catcher;
- tf->fixreg[1] = (register_t)sfp;
- tf->fixreg[FIRSTARG] = sig;
- tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
- if (SIGISMEMBER(psp->ps_siginfo, sig)) {
- /*
- * Signal handler installed with SA_SIGINFO.
- */
- tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
-
- /*
- * Fill siginfo structure.
- */
- sf.sf_si = ksi->ksi_info;
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_addr = (void *) ((tf->exc == EXC_DSI) ?
- tf->dar : tf->srr0);
- } else {
- /* Old FreeBSD-style arguments. */
- tf->fixreg[FIRSTARG+1] = code;
- tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
- tf->dar : tf->srr0;
- }
- mtx_unlock(&psp->ps_mtx);
- PROC_UNLOCK(p);
-
- tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
-
- /*
- * copy the frame out to userland.
- */
- if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
- /*
- * Process has trashed its stack. Kill it.
- */
- CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
- PROC_LOCK(p);
- sigexit(td, SIGILL);
- }
-
- CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
- tf->srr0, tf->fixreg[1]);
-
- PROC_LOCK(p);
- mtx_lock(&psp->ps_mtx);
-}
-
-int
-sigreturn(struct thread *td, struct sigreturn_args *uap)
-{
- struct proc *p;
- ucontext_t uc;
- int error;
-
- CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
-
- if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
- CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
- return (EFAULT);
- }
-
- error = set_mcontext(td, &uc.uc_mcontext);
- if (error != 0)
- return (error);
-
- p = td->td_proc;
- PROC_LOCK(p);
- td->td_sigmask = uc.uc_sigmask;
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
-
- CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
- td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
-
- return (EJUSTRETURN);
-}
-
-#ifdef COMPAT_FREEBSD4
-int
-freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
-{
-
- return sigreturn(td, (struct sigreturn_args *)uap);
-}
-#endif
-
-/*
- * Construct a PCB from a trapframe. This is called from kdb_trap() where
- * we want to start a backtrace from the function that caused us to enter
- * the debugger. We have the context in the trapframe, but base the trace
- * on the PCB. The PCB doesn't have to be perfect, as long as it contains
- * enough for a backtrace.
- */
-void
-makectx(struct trapframe *tf, struct pcb *pcb)
-{
-
- pcb->pcb_lr = tf->srr0;
- pcb->pcb_sp = tf->fixreg[1];
-}
-
-/*
- * get_mcontext/sendsig helper routine that doesn't touch the
- * proc lock
- */
-static int
-grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
-{
- struct pcb *pcb;
-
- pcb = td->td_pcb;
-
- memset(mcp, 0, sizeof(mcontext_t));
-
- mcp->mc_vers = _MC_VERSION;
- mcp->mc_flags = 0;
- memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe));
- if (flags & GET_MC_CLEAR_RET) {
- mcp->mc_gpr[3] = 0;
- mcp->mc_gpr[4] = 0;
- }
-
- /*
- * This assumes that floating-point context is *not* lazy,
- * so if the thread has used FP there would have been a
- * FP-unavailable exception that would have set things up
- * correctly.
- */
- if (pcb->pcb_flags & PCB_FPU) {
- KASSERT(td == curthread,
- ("get_mcontext: fp save not curthread"));
- critical_enter();
- save_fpu(td);
- critical_exit();
- mcp->mc_flags |= _MC_FP_VALID;
- memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
- memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double));
- }
-
- /* XXX Altivec context ? */
-
- mcp->mc_len = sizeof(*mcp);
-
- return (0);
-}
-
-int
-get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
-{
- int error;
-
- error = grab_mcontext(td, mcp, flags);
- if (error == 0) {
- PROC_LOCK(curthread->td_proc);
- mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
- PROC_UNLOCK(curthread->td_proc);
- }
-
- return (error);
-}
-
-int
-set_mcontext(struct thread *td, const mcontext_t *mcp)
-{
- struct pcb *pcb;
- struct trapframe *tf;
-
- pcb = td->td_pcb;
- tf = td->td_frame;
-
- if (mcp->mc_vers != _MC_VERSION ||
- mcp->mc_len != sizeof(*mcp))
- return (EINVAL);
-
- /*
- * Don't let the user set privileged MSR bits
- */
- if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) {
- return (EINVAL);
- }
-
- memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
-
- if (mcp->mc_flags & _MC_FP_VALID) {
- if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) {
- critical_enter();
- enable_fpu(td);
- critical_exit();
- }
- memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
- memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double));
- }
-
- /* XXX Altivec context? */
-
- return (0);
-}
-
-void
-cpu_boot(int howto)
-{
-}
-
-void
-cpu_initclocks(void)
-{
-
- decr_tc_init();
-}
-
-/* Get current clock frequency for the given cpu id. */
-int
-cpu_est_clockrate(int cpu_id, uint64_t *rate)
-{
-
- return (ENXIO);
-}
-
-/*
- * Shutdown the CPU as much as possible.
- */
-void
-cpu_halt(void)
-{
-
- OF_exit();
-}
-
-void
-cpu_idle(void)
-{
- /* TODO: Insert code to halt (until next interrupt) */
-
-#ifdef INVARIANTS
- if ((mfmsr() & PSL_EE) != PSL_EE) {
- struct thread *td = curthread;
- printf("td msr %x\n", td->td_md.md_saved_msr);
- panic("ints disabled in idleproc!");
- }
-#endif
-}
-
-/*
- * Set set up registers on exec.
- */
-void
-exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
-{
- struct trapframe *tf;
- struct ps_strings arginfo;
-
- tf = trapframe(td);
- bzero(tf, sizeof *tf);
- tf->fixreg[1] = -roundup(-stack + 8, 16);
-
- /*
- * XXX Machine-independent code has already copied arguments and
- * XXX environment to userland. Get them back here.
- */
- (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo));
-
- /*
- * Set up arguments for _start():
- * _start(argc, argv, envp, obj, cleanup, ps_strings);
- *
- * Notes:
- * - obj and cleanup are the auxilliary and termination
- * vectors. They are fixed up by ld.elf_so.
- * - ps_strings is a NetBSD extention, and will be
- * ignored by executables which are strictly
- * compliant with the SVR4 ABI.
- *
- * XXX We have to set both regs and retval here due to different
- * XXX calling convention in trap.c and init_main.c.
- */
- /*
- * XXX PG: these get overwritten in the syscall return code.
- * execve() should return EJUSTRETURN, like it does on NetBSD.
- * Emulate by setting the syscall return value cells. The
- * registers still have to be set for init's fork trampoline.
- */
- td->td_retval[0] = arginfo.ps_nargvstr;
- td->td_retval[1] = (register_t)arginfo.ps_argvstr;
- tf->fixreg[3] = arginfo.ps_nargvstr;
- tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
- tf->fixreg[5] = (register_t)arginfo.ps_envstr;
- tf->fixreg[6] = 0; /* auxillary vector */
- tf->fixreg[7] = 0; /* termination vector */
- tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
-
- tf->srr0 = entry;
- tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
- td->td_pcb->pcb_flags = 0;
-}
-
-int
-fill_regs(struct thread *td, struct reg *regs)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- memcpy(regs, tf, sizeof(struct reg));
-
- return (0);
-}
-
-int
-fill_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- /* No debug registers on PowerPC */
- return (ENOSYS);
-}
-
-int
-fill_fpregs(struct thread *td, struct fpreg *fpregs)
-{
- struct pcb *pcb;
-
- pcb = td->td_pcb;
-
- if ((pcb->pcb_flags & PCB_FPU) == 0)
- memset(fpregs, 0, sizeof(struct fpreg));
- else
- memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
-
- return (0);
-}
-
-int
-set_regs(struct thread *td, struct reg *regs)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- memcpy(tf, regs, sizeof(struct reg));
-
- return (0);
-}
-
-int
-set_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- /* No debug registers on PowerPC */
- return (ENOSYS);
-}
-
-int
-set_fpregs(struct thread *td, struct fpreg *fpregs)
-{
- struct pcb *pcb;
-
- pcb = td->td_pcb;
- if ((pcb->pcb_flags & PCB_FPU) == 0)
- enable_fpu(td);
- memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
-
- return (0);
-}
-
-int
-ptrace_set_pc(struct thread *td, unsigned long addr)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- tf->srr0 = (register_t)addr;
-
- return (0);
-}
-
-int
-ptrace_single_step(struct thread *td)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- tf->srr1 |= PSL_SE;
-
- return (0);
-}
-
-int
-ptrace_clear_single_step(struct thread *td)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- tf->srr1 &= ~PSL_SE;
-
- return (0);
-}
-
-/*
- * Initialise a struct pcpu.
- */
-void
-cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
-{
-
-}
-
-void
-spinlock_enter(void)
-{
- struct thread *td;
-
- td = curthread;
- if (td->td_md.md_spinlock_count == 0)
- td->td_md.md_saved_msr = intr_disable();
- td->td_md.md_spinlock_count++;
- critical_enter();
-}
-
-void
-spinlock_exit(void)
-{
- struct thread *td;
-
- td = curthread;
- critical_exit();
- td->td_md.md_spinlock_count--;
- if (td->td_md.md_spinlock_count == 0)
- intr_restore(td->td_md.md_saved_msr);
-}
-
-/*
- * kcopy(const void *src, void *dst, size_t len);
- *
- * Copy len bytes from src to dst, aborting if we encounter a fatal
- * page fault.
- *
- * kcopy() _must_ save and restore the old fault handler since it is
- * called by uiomove(), which may be in the path of servicing a non-fatal
- * page fault.
- */
-int
-kcopy(const void *src, void *dst, size_t len)
-{
- struct thread *td;
- faultbuf env, *oldfault;
- int rv;
-
- td = PCPU_GET(curthread);
- oldfault = td->td_pcb->pcb_onfault;
- if ((rv = setfault(env)) != 0) {
- td->td_pcb->pcb_onfault = oldfault;
- return rv;
- }
-
- memcpy(dst, src, len);
-
- td->td_pcb->pcb_onfault = oldfault;
- return (0);
-}
-
-void
-asm_panic(char *pstr)
-{
- panic(pstr);
-}
-
-int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */
-
-int
-db_trap_glue(struct trapframe *frame)
-{
- if (!(frame->srr1 & PSL_PR)
- && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC
- || (frame->exc == EXC_PGM
- && (frame->srr1 & 0x20000))
- || frame->exc == EXC_BPT
- || frame->exc == EXC_DSI)) {
- int type = frame->exc;
- if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
- type = T_BREAKPOINT;
- }
- return (kdb_trap(type, 0, frame));
- }
-
- return (0);
-}
diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c
deleted file mode 100644
index db2c3bb..0000000
--- a/sys/powerpc/powerpc/mmu_oea.c
+++ /dev/null
@@ -1,2544 +0,0 @@
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc.
- *
- * 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- *
- * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
- */
-/*-
- * Copyright (C) 2001 Benno Rice.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Manages physical address maps.
- *
- * In addition to hardware address maps, this module is called upon to
- * provide software-use-only maps which may or may not be stored in the
- * same form as hardware maps. These pseudo-maps are used to store
- * intermediate results from copy operations to and from address spaces.
- *
- * Since the information managed by this module is also stored by the
- * logical address mapping module, this module may throw away valid virtual
- * to physical mappings at almost any time. However, invalidations of
- * mappings must be done as requested.
- *
- * In order to cope with hardware architectures which make virtual to
- * physical map invalidates expensive, this module may delay invalidate
- * reduced protection operations until such time as they are actually
- * necessary. This module is given full information as to which processors
- * are currently using which maps, and to when physical maps must be made
- * correct.
- */
-
-#include "opt_kstack_pages.h"
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/msgbuf.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-#include <sys/vmmeter.h>
-
-#include <dev/ofw/openfirm.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_pageout.h>
-#include <vm/vm_pager.h>
-#include <vm/uma.h>
-
-#include <machine/cpu.h>
-#include <machine/powerpc.h>
-#include <machine/bat.h>
-#include <machine/frame.h>
-#include <machine/md_var.h>
-#include <machine/psl.h>
-#include <machine/pte.h>
-#include <machine/sr.h>
-#include <machine/mmuvar.h>
-
-#include "mmu_if.h"
-
-#define MOEA_DEBUG
-
-#define TODO panic("%s: not implemented", __func__);
-
-#define TLBIE(va) __asm __volatile("tlbie %0" :: "r"(va))
-#define TLBSYNC() __asm __volatile("tlbsync");
-#define SYNC() __asm __volatile("sync");
-#define EIEIO() __asm __volatile("eieio");
-
-#define VSID_MAKE(sr, hash) ((sr) | (((hash) & 0xfffff) << 4))
-#define VSID_TO_SR(vsid) ((vsid) & 0xf)
-#define VSID_TO_HASH(vsid) (((vsid) >> 4) & 0xfffff)
-
-#define PVO_PTEGIDX_MASK 0x007 /* which PTEG slot */
-#define PVO_PTEGIDX_VALID 0x008 /* slot is valid */
-#define PVO_WIRED 0x010 /* PVO entry is wired */
-#define PVO_MANAGED 0x020 /* PVO entry is managed */
-#define PVO_EXECUTABLE 0x040 /* PVO entry is executable */
-#define PVO_BOOTSTRAP 0x080 /* PVO entry allocated during
- bootstrap */
-#define PVO_FAKE 0x100 /* fictitious phys page */
-#define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF)
-#define PVO_ISEXECUTABLE(pvo) ((pvo)->pvo_vaddr & PVO_EXECUTABLE)
-#define PVO_ISFAKE(pvo) ((pvo)->pvo_vaddr & PVO_FAKE)
-#define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
-#define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
-#define PVO_PTEGIDX_CLR(pvo) \
- ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
-#define PVO_PTEGIDX_SET(pvo, i) \
- ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
-
-#define MOEA_PVO_CHECK(pvo)
-
-struct ofw_map {
- vm_offset_t om_va;
- vm_size_t om_len;
- vm_offset_t om_pa;
- u_int om_mode;
-};
-
-/*
- * Map of physical memory regions.
- */
-static struct mem_region *regions;
-static struct mem_region *pregions;
-u_int phys_avail_count;
-int regions_sz, pregions_sz;
-static struct ofw_map *translations;
-
-extern struct pmap ofw_pmap;
-
-
-
-/*
- * Lock for the pteg and pvo tables.
- */
-struct mtx moea_table_mutex;
-
-/*
- * PTEG data.
- */
-static struct pteg *moea_pteg_table;
-u_int moea_pteg_count;
-u_int moea_pteg_mask;
-
-/*
- * PVO data.
- */
-struct pvo_head *moea_pvo_table; /* pvo entries by pteg index */
-struct pvo_head moea_pvo_kunmanaged =
- LIST_HEAD_INITIALIZER(moea_pvo_kunmanaged); /* list of unmanaged pages */
-struct pvo_head moea_pvo_unmanaged =
- LIST_HEAD_INITIALIZER(moea_pvo_unmanaged); /* list of unmanaged pages */
-
-uma_zone_t moea_upvo_zone; /* zone for pvo entries for unmanaged pages */
-uma_zone_t moea_mpvo_zone; /* zone for pvo entries for managed pages */
-
-#define BPVO_POOL_SIZE 32768
-static struct pvo_entry *moea_bpvo_pool;
-static int moea_bpvo_pool_index = 0;
-
-#define VSID_NBPW (sizeof(u_int32_t) * 8)
-static u_int moea_vsid_bitmap[NPMAPS / VSID_NBPW];
-
-static boolean_t moea_initialized = FALSE;
-
-/*
- * Statistics.
- */
-u_int moea_pte_valid = 0;
-u_int moea_pte_overflow = 0;
-u_int moea_pte_replacements = 0;
-u_int moea_pvo_entries = 0;
-u_int moea_pvo_enter_calls = 0;
-u_int moea_pvo_remove_calls = 0;
-u_int moea_pte_spills = 0;
-SYSCTL_INT(_machdep, OID_AUTO, moea_pte_valid, CTLFLAG_RD, &moea_pte_valid,
- 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pte_overflow, CTLFLAG_RD,
- &moea_pte_overflow, 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pte_replacements, CTLFLAG_RD,
- &moea_pte_replacements, 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_entries, CTLFLAG_RD, &moea_pvo_entries,
- 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_enter_calls, CTLFLAG_RD,
- &moea_pvo_enter_calls, 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_remove_calls, CTLFLAG_RD,
- &moea_pvo_remove_calls, 0, "");
-SYSCTL_INT(_machdep, OID_AUTO, moea_pte_spills, CTLFLAG_RD,
- &moea_pte_spills, 0, "");
-
-struct pvo_entry *moea_pvo_zeropage;
-struct mtx moea_pvo_zeropage_mtx;
-
-vm_offset_t moea_rkva_start = VM_MIN_KERNEL_ADDRESS;
-u_int moea_rkva_count = 4;
-
-/*
- * Allocate physical memory for use in moea_bootstrap.
- */
-static vm_offset_t moea_bootstrap_alloc(vm_size_t, u_int);
-
-/*
- * PTE calls.
- */
-static int moea_pte_insert(u_int, struct pte *);
-
-/*
- * PVO calls.
- */
-static int moea_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
- vm_offset_t, vm_offset_t, u_int, int);
-static void moea_pvo_remove(struct pvo_entry *, int);
-static struct pvo_entry *moea_pvo_find_va(pmap_t, vm_offset_t, int *);
-static struct pte *moea_pvo_to_pte(const struct pvo_entry *, int);
-
-/*
- * Utility routines.
- */
-static void moea_enter_locked(pmap_t, vm_offset_t, vm_page_t,
- vm_prot_t, boolean_t);
-static struct pvo_entry *moea_rkva_alloc(mmu_t);
-static void moea_pa_map(struct pvo_entry *, vm_offset_t,
- struct pte *, int *);
-static void moea_pa_unmap(struct pvo_entry *, struct pte *, int *);
-static void moea_syncicache(vm_offset_t, vm_size_t);
-static boolean_t moea_query_bit(vm_page_t, int);
-static u_int moea_clear_bit(vm_page_t, int, int *);
-static void moea_kremove(mmu_t, vm_offset_t);
-static void tlbia(void);
-int moea_pte_spill(vm_offset_t);
-
-/*
- * Kernel MMU interface
- */
-void moea_change_wiring(mmu_t, pmap_t, vm_offset_t, boolean_t);
-void moea_clear_modify(mmu_t, vm_page_t);
-void moea_clear_reference(mmu_t, vm_page_t);
-void moea_copy_page(mmu_t, vm_page_t, vm_page_t);
-void moea_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, boolean_t);
-void moea_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t,
- vm_prot_t);
-void moea_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t);
-vm_paddr_t moea_extract(mmu_t, pmap_t, vm_offset_t);
-vm_page_t moea_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
-void moea_init(mmu_t);
-boolean_t moea_is_modified(mmu_t, vm_page_t);
-boolean_t moea_ts_referenced(mmu_t, vm_page_t);
-vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
-boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t);
-int moea_page_wired_mappings(mmu_t, vm_page_t);
-void moea_pinit(mmu_t, pmap_t);
-void moea_pinit0(mmu_t, pmap_t);
-void moea_protect(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_prot_t);
-void moea_qenter(mmu_t, vm_offset_t, vm_page_t *, int);
-void moea_qremove(mmu_t, vm_offset_t, int);
-void moea_release(mmu_t, pmap_t);
-void moea_remove(mmu_t, pmap_t, vm_offset_t, vm_offset_t);
-void moea_remove_all(mmu_t, vm_page_t);
-void moea_remove_write(mmu_t, vm_page_t);
-void moea_zero_page(mmu_t, vm_page_t);
-void moea_zero_page_area(mmu_t, vm_page_t, int, int);
-void moea_zero_page_idle(mmu_t, vm_page_t);
-void moea_activate(mmu_t, struct thread *);
-void moea_deactivate(mmu_t, struct thread *);
-void moea_bootstrap(mmu_t, vm_offset_t, vm_offset_t);
-void *moea_mapdev(mmu_t, vm_offset_t, vm_size_t);
-void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t);
-vm_offset_t moea_kextract(mmu_t, vm_offset_t);
-void moea_kenter(mmu_t, vm_offset_t, vm_offset_t);
-boolean_t moea_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
-boolean_t moea_page_executable(mmu_t, vm_page_t);
-
-static mmu_method_t moea_methods[] = {
- MMUMETHOD(mmu_change_wiring, moea_change_wiring),
- MMUMETHOD(mmu_clear_modify, moea_clear_modify),
- MMUMETHOD(mmu_clear_reference, moea_clear_reference),
- MMUMETHOD(mmu_copy_page, moea_copy_page),
- MMUMETHOD(mmu_enter, moea_enter),
- MMUMETHOD(mmu_enter_object, moea_enter_object),
- MMUMETHOD(mmu_enter_quick, moea_enter_quick),
- MMUMETHOD(mmu_extract, moea_extract),
- MMUMETHOD(mmu_extract_and_hold, moea_extract_and_hold),
- MMUMETHOD(mmu_init, moea_init),
- MMUMETHOD(mmu_is_modified, moea_is_modified),
- MMUMETHOD(mmu_ts_referenced, moea_ts_referenced),
- MMUMETHOD(mmu_map, moea_map),
- MMUMETHOD(mmu_page_exists_quick,moea_page_exists_quick),
- MMUMETHOD(mmu_page_wired_mappings,moea_page_wired_mappings),
- MMUMETHOD(mmu_pinit, moea_pinit),
- MMUMETHOD(mmu_pinit0, moea_pinit0),
- MMUMETHOD(mmu_protect, moea_protect),
- MMUMETHOD(mmu_qenter, moea_qenter),
- MMUMETHOD(mmu_qremove, moea_qremove),
- MMUMETHOD(mmu_release, moea_release),
- MMUMETHOD(mmu_remove, moea_remove),
- MMUMETHOD(mmu_remove_all, moea_remove_all),
- MMUMETHOD(mmu_remove_write, moea_remove_write),
- MMUMETHOD(mmu_zero_page, moea_zero_page),
- MMUMETHOD(mmu_zero_page_area, moea_zero_page_area),
- MMUMETHOD(mmu_zero_page_idle, moea_zero_page_idle),
- MMUMETHOD(mmu_activate, moea_activate),
- MMUMETHOD(mmu_deactivate, moea_deactivate),
-
- /* Internal interfaces */
- MMUMETHOD(mmu_bootstrap, moea_bootstrap),
- MMUMETHOD(mmu_mapdev, moea_mapdev),
- MMUMETHOD(mmu_unmapdev, moea_unmapdev),
- MMUMETHOD(mmu_kextract, moea_kextract),
- MMUMETHOD(mmu_kenter, moea_kenter),
- MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped),
- MMUMETHOD(mmu_page_executable, moea_page_executable),
-
- { 0, 0 }
-};
-
-static mmu_def_t oea_mmu = {
- MMU_TYPE_OEA,
- moea_methods,
- 0
-};
-MMU_DEF(oea_mmu);
-
-
-static __inline int
-va_to_sr(u_int *sr, vm_offset_t va)
-{
- return (sr[(uintptr_t)va >> ADDR_SR_SHFT]);
-}
-
-static __inline u_int
-va_to_pteg(u_int sr, vm_offset_t addr)
-{
- u_int hash;
-
- hash = (sr & SR_VSID_MASK) ^ (((u_int)addr & ADDR_PIDX) >>
- ADDR_PIDX_SHFT);
- return (hash & moea_pteg_mask);
-}
-
-static __inline struct pvo_head *
-pa_to_pvoh(vm_offset_t pa, vm_page_t *pg_p)
-{
- struct vm_page *pg;
-
- pg = PHYS_TO_VM_PAGE(pa);
-
- if (pg_p != NULL)
- *pg_p = pg;
-
- if (pg == NULL)
- return (&moea_pvo_unmanaged);
-
- return (&pg->md.mdpg_pvoh);
-}
-
-static __inline struct pvo_head *
-vm_page_to_pvoh(vm_page_t m)
-{
-
- return (&m->md.mdpg_pvoh);
-}
-
-static __inline void
-moea_attr_clear(vm_page_t m, int ptebit)
-{
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- m->md.mdpg_attrs &= ~ptebit;
-}
-
-static __inline int
-moea_attr_fetch(vm_page_t m)
-{
-
- return (m->md.mdpg_attrs);
-}
-
-static __inline void
-moea_attr_save(vm_page_t m, int ptebit)
-{
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- m->md.mdpg_attrs |= ptebit;
-}
-
-static __inline int
-moea_pte_compare(const struct pte *pt, const struct pte *pvo_pt)
-{
- if (pt->pte_hi == pvo_pt->pte_hi)
- return (1);
-
- return (0);
-}
-
-static __inline int
-moea_pte_match(struct pte *pt, u_int sr, vm_offset_t va, int which)
-{
- return (pt->pte_hi & ~PTE_VALID) ==
- (((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
- ((va >> ADDR_API_SHFT) & PTE_API) | which);
-}
-
-static __inline void
-moea_pte_create(struct pte *pt, u_int sr, vm_offset_t va, u_int pte_lo)
-{
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
-
- /*
- * Construct a PTE. Default to IMB initially. Valid bit only gets
- * set when the real pte is set in memory.
- *
- * Note: Don't set the valid bit for correct operation of tlb update.
- */
- pt->pte_hi = ((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
- (((va & ADDR_PIDX) >> ADDR_API_SHFT) & PTE_API);
- pt->pte_lo = pte_lo;
-}
-
-static __inline void
-moea_pte_synch(struct pte *pt, struct pte *pvo_pt)
-{
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
- pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF | PTE_CHG);
-}
-
-static __inline void
-moea_pte_clear(struct pte *pt, vm_offset_t va, int ptebit)
-{
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
-
- /*
- * As shown in Section 7.6.3.2.3
- */
- pt->pte_lo &= ~ptebit;
- TLBIE(va);
- EIEIO();
- TLBSYNC();
- SYNC();
-}
-
-static __inline void
-moea_pte_set(struct pte *pt, struct pte *pvo_pt)
-{
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
- pvo_pt->pte_hi |= PTE_VALID;
-
- /*
- * Update the PTE as defined in section 7.6.3.1.
- * Note that the REF/CHG bits are from pvo_pt and thus should havce
- * been saved so this routine can restore them (if desired).
- */
- pt->pte_lo = pvo_pt->pte_lo;
- EIEIO();
- pt->pte_hi = pvo_pt->pte_hi;
- SYNC();
- moea_pte_valid++;
-}
-
-static __inline void
-moea_pte_unset(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
-{
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
- pvo_pt->pte_hi &= ~PTE_VALID;
-
- /*
- * Force the reg & chg bits back into the PTEs.
- */
- SYNC();
-
- /*
- * Invalidate the pte.
- */
- pt->pte_hi &= ~PTE_VALID;
-
- SYNC();
- TLBIE(va);
- EIEIO();
- TLBSYNC();
- SYNC();
-
- /*
- * Save the reg & chg bits.
- */
- moea_pte_synch(pt, pvo_pt);
- moea_pte_valid--;
-}
-
-static __inline void
-moea_pte_change(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
-{
-
- /*
- * Invalidate the PTE
- */
- moea_pte_unset(pt, pvo_pt, va);
- moea_pte_set(pt, pvo_pt);
-}
-
-/*
- * Quick sort callout for comparing memory regions.
- */
-static int mr_cmp(const void *a, const void *b);
-static int om_cmp(const void *a, const void *b);
-
-static int
-mr_cmp(const void *a, const void *b)
-{
- const struct mem_region *regiona;
- const struct mem_region *regionb;
-
- regiona = a;
- regionb = b;
- if (regiona->mr_start < regionb->mr_start)
- return (-1);
- else if (regiona->mr_start > regionb->mr_start)
- return (1);
- else
- return (0);
-}
-
-static int
-om_cmp(const void *a, const void *b)
-{
- const struct ofw_map *mapa;
- const struct ofw_map *mapb;
-
- mapa = a;
- mapb = b;
- if (mapa->om_pa < mapb->om_pa)
- return (-1);
- else if (mapa->om_pa > mapb->om_pa)
- return (1);
- else
- return (0);
-}
-
-void
-moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
-{
- ihandle_t mmui;
- phandle_t chosen, mmu;
- int sz;
- int i, j;
- int ofw_mappings;
- vm_size_t size, physsz, hwphyssz;
- vm_offset_t pa, va, off;
- u_int batl, batu;
-
- /*
- * Set up BAT0 to map the lowest 256 MB area
- */
- battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
- battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
-
- /*
- * Map PCI memory space.
- */
- battable[0x8].batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
- battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
-
- battable[0x9].batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
- battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
-
- battable[0xa].batl = BATL(0xa0000000, BAT_I|BAT_G, BAT_PP_RW);
- battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
-
- battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW);
- battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs);
-
- /*
- * Map obio devices.
- */
- battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW);
- battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
-
- /*
- * Use an IBAT and a DBAT to map the bottom segment of memory
- * where we are.
- */
- batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
- __asm (".balign 32; \n"
- "mtibatu 0,%0; mtibatl 0,%1; isync; \n"
- "mtdbatu 0,%0; mtdbatl 0,%1; isync"
- :: "r"(batu), "r"(batl));
-
-#if 0
- /* map frame buffer */
- batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
- __asm ("mtdbatu 1,%0; mtdbatl 1,%1; isync"
- :: "r"(batu), "r"(batl));
-#endif
-
-#if 1
- /* map pci space */
- batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
- __asm ("mtdbatu 1,%0; mtdbatl 1,%1; isync"
- :: "r"(batu), "r"(batl));
-#endif
-
- /*
- * Set the start and end of kva.
- */
- virtual_avail = VM_MIN_KERNEL_ADDRESS;
- virtual_end = VM_MAX_KERNEL_ADDRESS;
-
- mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
- CTR0(KTR_PMAP, "moea_bootstrap: physical memory");
-
- qsort(pregions, pregions_sz, sizeof(*pregions), mr_cmp);
- for (i = 0; i < pregions_sz; i++) {
- vm_offset_t pa;
- vm_offset_t end;
-
- CTR3(KTR_PMAP, "physregion: %#x - %#x (%#x)",
- pregions[i].mr_start,
- pregions[i].mr_start + pregions[i].mr_size,
- pregions[i].mr_size);
- /*
- * Install entries into the BAT table to allow all
- * of physmem to be convered by on-demand BAT entries.
- * The loop will sometimes set the same battable element
- * twice, but that's fine since they won't be used for
- * a while yet.
- */
- pa = pregions[i].mr_start & 0xf0000000;
- end = pregions[i].mr_start + pregions[i].mr_size;
- do {
- u_int n = pa >> ADDR_SR_SHFT;
-
- battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
- battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
- pa += SEGMENT_LENGTH;
- } while (pa < end);
- }
-
- if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz)
- panic("moea_bootstrap: phys_avail too small");
- qsort(regions, regions_sz, sizeof(*regions), mr_cmp);
- phys_avail_count = 0;
- physsz = 0;
- hwphyssz = 0;
- TUNABLE_ULONG_FETCH("hw.physmem", (u_long *) &hwphyssz);
- for (i = 0, j = 0; i < regions_sz; i++, j += 2) {
- CTR3(KTR_PMAP, "region: %#x - %#x (%#x)", regions[i].mr_start,
- regions[i].mr_start + regions[i].mr_size,
- regions[i].mr_size);
- if (hwphyssz != 0 &&
- (physsz + regions[i].mr_size) >= hwphyssz) {
- if (physsz < hwphyssz) {
- phys_avail[j] = regions[i].mr_start;
- phys_avail[j + 1] = regions[i].mr_start +
- hwphyssz - physsz;
- physsz = hwphyssz;
- phys_avail_count++;
- }
- break;
- }
- phys_avail[j] = regions[i].mr_start;
- phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size;
- phys_avail_count++;
- physsz += regions[i].mr_size;
- }
- physmem = btoc(physsz);
-
- /*
- * Allocate PTEG table.
- */
-#ifdef PTEGCOUNT
- moea_pteg_count = PTEGCOUNT;
-#else
- moea_pteg_count = 0x1000;
-
- while (moea_pteg_count < physmem)
- moea_pteg_count <<= 1;
-
- moea_pteg_count >>= 1;
-#endif /* PTEGCOUNT */
-
- size = moea_pteg_count * sizeof(struct pteg);
- CTR2(KTR_PMAP, "moea_bootstrap: %d PTEGs, %d bytes", moea_pteg_count,
- size);
- moea_pteg_table = (struct pteg *)moea_bootstrap_alloc(size, size);
- CTR1(KTR_PMAP, "moea_bootstrap: PTEG table at %p", moea_pteg_table);
- bzero((void *)moea_pteg_table, moea_pteg_count * sizeof(struct pteg));
- moea_pteg_mask = moea_pteg_count - 1;
-
- /*
- * Allocate pv/overflow lists.
- */
- size = sizeof(struct pvo_head) * moea_pteg_count;
- moea_pvo_table = (struct pvo_head *)moea_bootstrap_alloc(size,
- PAGE_SIZE);
- CTR1(KTR_PMAP, "moea_bootstrap: PVO table at %p", moea_pvo_table);
- for (i = 0; i < moea_pteg_count; i++)
- LIST_INIT(&moea_pvo_table[i]);
-
- /*
- * Initialize the lock that synchronizes access to the pteg and pvo
- * tables.
- */
- mtx_init(&moea_table_mutex, "pmap table", NULL, MTX_DEF |
- MTX_RECURSE);
-
- /*
- * Allocate the message buffer.
- */
- msgbuf_phys = moea_bootstrap_alloc(MSGBUF_SIZE, 0);
-
- /*
- * Initialise the unmanaged pvo pool.
- */
- moea_bpvo_pool = (struct pvo_entry *)moea_bootstrap_alloc(
- BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0);
- moea_bpvo_pool_index = 0;
-
- /*
- * Make sure kernel vsid is allocated as well as VSID 0.
- */
- moea_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS - 1)) / VSID_NBPW]
- |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
- moea_vsid_bitmap[0] |= 1;
-
- /*
- * Set up the Open Firmware pmap and add it's mappings.
- */
- moea_pinit(mmup, &ofw_pmap);
- ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
- ofw_pmap.pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT;
- if ((chosen = OF_finddevice("/chosen")) == -1)
- panic("moea_bootstrap: can't find /chosen");
- OF_getprop(chosen, "mmu", &mmui, 4);
- if ((mmu = OF_instance_to_package(mmui)) == -1)
- panic("moea_bootstrap: can't get mmu package");
- if ((sz = OF_getproplen(mmu, "translations")) == -1)
- panic("moea_bootstrap: can't get ofw translation count");
- translations = NULL;
- for (i = 0; phys_avail[i] != 0; i += 2) {
- if (phys_avail[i + 1] >= sz) {
- translations = (struct ofw_map *)phys_avail[i];
- break;
- }
- }
- if (translations == NULL)
- panic("moea_bootstrap: no space to copy translations");
- bzero(translations, sz);
- if (OF_getprop(mmu, "translations", translations, sz) == -1)
- panic("moea_bootstrap: can't get ofw translations");
- CTR0(KTR_PMAP, "moea_bootstrap: translations");
- sz /= sizeof(*translations);
- qsort(translations, sz, sizeof (*translations), om_cmp);
- for (i = 0, ofw_mappings = 0; i < sz; i++) {
- CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
- translations[i].om_pa, translations[i].om_va,
- translations[i].om_len);
-
- /*
- * If the mapping is 1:1, let the RAM and device on-demand
- * BAT tables take care of the translation.
- */
- if (translations[i].om_va == translations[i].om_pa)
- continue;
-
- /* Enter the pages */
- for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
- struct vm_page m;
-
- m.phys_addr = translations[i].om_pa + off;
- PMAP_LOCK(&ofw_pmap);
- moea_enter_locked(&ofw_pmap,
- translations[i].om_va + off, &m,
- VM_PROT_ALL, 1);
- PMAP_UNLOCK(&ofw_pmap);
- ofw_mappings++;
- }
- }
-#ifdef SMP
- TLBSYNC();
-#endif
-
- /*
- * Initialize the kernel pmap (which is statically allocated).
- */
- PMAP_LOCK_INIT(kernel_pmap);
- for (i = 0; i < 16; i++) {
- kernel_pmap->pm_sr[i] = EMPTY_SEGMENT;
- }
- kernel_pmap->pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
- kernel_pmap->pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT;
- kernel_pmap->pm_active = ~0;
-
- /*
- * Allocate a kernel stack with a guard page for thread0 and map it
- * into the kernel page map.
- */
- pa = moea_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, 0);
- kstack0_phys = pa;
- kstack0 = virtual_avail + (KSTACK_GUARD_PAGES * PAGE_SIZE);
- CTR2(KTR_PMAP, "moea_bootstrap: kstack0 at %#x (%#x)", kstack0_phys,
- kstack0);
- virtual_avail += (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE;
- for (i = 0; i < KSTACK_PAGES; i++) {
- pa = kstack0_phys + i * PAGE_SIZE;
- va = kstack0 + i * PAGE_SIZE;
- moea_kenter(mmup, va, pa);
- TLBIE(va);
- }
-
- /*
- * Calculate the last available physical address.
- */
- for (i = 0; phys_avail[i + 2] != 0; i += 2)
- ;
- Maxmem = powerpc_btop(phys_avail[i + 1]);
-
- /*
- * Allocate virtual address space for the message buffer.
- */
- msgbufp = (struct msgbuf *)virtual_avail;
- virtual_avail += round_page(MSGBUF_SIZE);
-
- /*
- * Initialize hardware.
- */
- for (i = 0; i < 16; i++) {
- mtsrin(i << ADDR_SR_SHFT, EMPTY_SEGMENT);
- }
- __asm __volatile ("mtsr %0,%1"
- :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
- __asm __volatile ("mtsr %0,%1"
- :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
- __asm __volatile ("sync; mtsdr1 %0; isync"
- :: "r"((u_int)moea_pteg_table | (moea_pteg_mask >> 10)));
- tlbia();
-
- pmap_bootstrapped++;
-}
-
-/*
- * Activate a user pmap. The pmap must be activated before it's address
- * space can be accessed in any way.
- */
-void
-moea_activate(mmu_t mmu, struct thread *td)
-{
- pmap_t pm, pmr;
-
- /*
- * Load all the data we need up front to encourage the compiler to
- * not issue any loads while we have interrupts disabled below.
- */
- pm = &td->td_proc->p_vmspace->vm_pmap;
-
- if ((pmr = (pmap_t)moea_kextract(mmu, (vm_offset_t)pm)) == NULL)
- pmr = pm;
-
- pm->pm_active |= PCPU_GET(cpumask);
- PCPU_SET(curpmap, pmr);
-}
-
-void
-moea_deactivate(mmu_t mmu, struct thread *td)
-{
- pmap_t pm;
-
- pm = &td->td_proc->p_vmspace->vm_pmap;
- pm->pm_active &= ~(PCPU_GET(cpumask));
- PCPU_SET(curpmap, NULL);
-}
-
-void
-moea_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
-{
- struct pvo_entry *pvo;
-
- PMAP_LOCK(pm);
- pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
-
- if (pvo != NULL) {
- if (wired) {
- if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
- pm->pm_stats.wired_count++;
- pvo->pvo_vaddr |= PVO_WIRED;
- } else {
- if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
- pm->pm_stats.wired_count--;
- pvo->pvo_vaddr &= ~PVO_WIRED;
- }
- }
- PMAP_UNLOCK(pm);
-}
-
-void
-moea_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst)
-{
- vm_offset_t dst;
- vm_offset_t src;
-
- dst = VM_PAGE_TO_PHYS(mdst);
- src = VM_PAGE_TO_PHYS(msrc);
-
- kcopy((void *)src, (void *)dst, PAGE_SIZE);
-}
-
-/*
- * Zero a page of physical memory by temporarily mapping it into the tlb.
- */
-void
-moea_zero_page(mmu_t mmu, vm_page_t m)
-{
- vm_offset_t pa = VM_PAGE_TO_PHYS(m);
- caddr_t va;
-
- if (pa < SEGMENT_LENGTH) {
- va = (caddr_t) pa;
- } else if (moea_initialized) {
- if (moea_pvo_zeropage == NULL) {
- moea_pvo_zeropage = moea_rkva_alloc(mmu);
- mtx_init(&moea_pvo_zeropage_mtx, "pvo zero page",
- NULL, MTX_DEF);
- }
- mtx_lock(&moea_pvo_zeropage_mtx);
- moea_pa_map(moea_pvo_zeropage, pa, NULL, NULL);
- va = (caddr_t)PVO_VADDR(moea_pvo_zeropage);
- } else {
- panic("moea_zero_page: can't zero pa %#x", pa);
- }
-
- bzero(va, PAGE_SIZE);
-
- if (pa >= SEGMENT_LENGTH) {
- moea_pa_unmap(moea_pvo_zeropage, NULL, NULL);
- mtx_unlock(&moea_pvo_zeropage_mtx);
- }
-}
-
-void
-moea_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
-{
- vm_offset_t pa = VM_PAGE_TO_PHYS(m);
- caddr_t va;
-
- if (pa < SEGMENT_LENGTH) {
- va = (caddr_t) pa;
- } else if (moea_initialized) {
- if (moea_pvo_zeropage == NULL) {
- moea_pvo_zeropage = moea_rkva_alloc(mmu);
- mtx_init(&moea_pvo_zeropage_mtx, "pvo zero page",
- NULL, MTX_DEF);
- }
- mtx_lock(&moea_pvo_zeropage_mtx);
- moea_pa_map(moea_pvo_zeropage, pa, NULL, NULL);
- va = (caddr_t)PVO_VADDR(moea_pvo_zeropage);
- } else {
- panic("moea_zero_page: can't zero pa %#x", pa);
- }
-
- bzero(va + off, size);
-
- if (pa >= SEGMENT_LENGTH) {
- moea_pa_unmap(moea_pvo_zeropage, NULL, NULL);
- mtx_unlock(&moea_pvo_zeropage_mtx);
- }
-}
-
-void
-moea_zero_page_idle(mmu_t mmu, vm_page_t m)
-{
-
- moea_zero_page(mmu, m);
-}
-
-/*
- * Map the given physical page at the specified virtual address in the
- * target pmap with the protection requested. If specified the page
- * will be wired down.
- */
-void
-moea_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
- boolean_t wired)
-{
-
- vm_page_lock_queues();
- PMAP_LOCK(pmap);
- moea_enter_locked(pmap, va, m, prot, wired);
- vm_page_unlock_queues();
- PMAP_UNLOCK(pmap);
-}
-
-/*
- * Map the given physical page at the specified virtual address in the
- * target pmap with the protection requested. If specified the page
- * will be wired down.
- *
- * The page queues and pmap must be locked.
- */
-static void
-moea_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
- boolean_t wired)
-{
- struct pvo_head *pvo_head;
- uma_zone_t zone;
- vm_page_t pg;
- u_int pte_lo, pvo_flags, was_exec, i;
- int error;
-
- if (!moea_initialized) {
- pvo_head = &moea_pvo_kunmanaged;
- zone = moea_upvo_zone;
- pvo_flags = 0;
- pg = NULL;
- was_exec = PTE_EXEC;
- } else {
- pvo_head = vm_page_to_pvoh(m);
- pg = m;
- zone = moea_mpvo_zone;
- pvo_flags = PVO_MANAGED;
- was_exec = 0;
- }
- if (pmap_bootstrapped)
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
-
- /* XXX change the pvo head for fake pages */
- if ((m->flags & PG_FICTITIOUS) == PG_FICTITIOUS)
- pvo_head = &moea_pvo_kunmanaged;
-
- /*
- * If this is a managed page, and it's the first reference to the page,
- * clear the execness of the page. Otherwise fetch the execness.
- */
- if ((pg != NULL) && ((m->flags & PG_FICTITIOUS) == 0)) {
- if (LIST_EMPTY(pvo_head)) {
- moea_attr_clear(pg, PTE_EXEC);
- } else {
- was_exec = moea_attr_fetch(pg) & PTE_EXEC;
- }
- }
-
- /*
- * Assume the page is cache inhibited and access is guarded unless
- * it's in our available memory array.
- */
- pte_lo = PTE_I | PTE_G;
- for (i = 0; i < pregions_sz; i++) {
- if ((VM_PAGE_TO_PHYS(m) >= pregions[i].mr_start) &&
- (VM_PAGE_TO_PHYS(m) <
- (pregions[i].mr_start + pregions[i].mr_size))) {
- pte_lo &= ~(PTE_I | PTE_G);
- break;
- }
- }
-
- if (prot & VM_PROT_WRITE) {
- pte_lo |= PTE_BW;
- if (pmap_bootstrapped)
- vm_page_flag_set(m, PG_WRITEABLE);
- } else
- pte_lo |= PTE_BR;
-
- if (prot & VM_PROT_EXECUTE)
- pvo_flags |= PVO_EXECUTABLE;
-
- if (wired)
- pvo_flags |= PVO_WIRED;
-
- if ((m->flags & PG_FICTITIOUS) != 0)
- pvo_flags |= PVO_FAKE;
-
- error = moea_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
- pte_lo, pvo_flags);
-
- /*
- * Flush the real page from the instruction cache if this page is
- * mapped executable and cacheable and was not previously mapped (or
- * was not mapped executable).
- */
- if (error == 0 && (pvo_flags & PVO_EXECUTABLE) &&
- (pte_lo & PTE_I) == 0 && was_exec == 0) {
- /*
- * Flush the real memory from the cache.
- */
- moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
- if (pg != NULL)
- moea_attr_save(pg, PTE_EXEC);
- }
-
- /* XXX syncicache always until problems are sorted */
- moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
-}
-
-/*
- * Maps a sequence of resident pages belonging to the same object.
- * The sequence begins with the given page m_start. This page is
- * mapped at the given virtual address start. Each subsequent page is
- * mapped at a virtual address that is offset from start by the same
- * amount as the page is offset from m_start within the object. The
- * last page in the sequence is the page with the largest offset from
- * m_start that can be mapped at a virtual address less than the given
- * virtual address end. Not every virtual page between start and end
- * is mapped; only those for which a resident page exists with the
- * corresponding offset from m_start are mapped.
- */
-void
-moea_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
- vm_page_t m_start, vm_prot_t prot)
-{
- vm_page_t m;
- vm_pindex_t diff, psize;
-
- psize = atop(end - start);
- m = m_start;
- PMAP_LOCK(pm);
- while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
- moea_enter_locked(pm, start + ptoa(diff), m, prot &
- (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
- m = TAILQ_NEXT(m, listq);
- }
- PMAP_UNLOCK(pm);
-}
-
-void
-moea_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m,
- vm_prot_t prot)
-{
-
- PMAP_LOCK(pm);
- moea_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
- FALSE);
- PMAP_UNLOCK(pm);
-
-}
-
-vm_paddr_t
-moea_extract(mmu_t mmu, pmap_t pm, vm_offset_t va)
-{
- struct pvo_entry *pvo;
- vm_paddr_t pa;
-
- PMAP_LOCK(pm);
- pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
- if (pvo == NULL)
- pa = 0;
- else
- pa = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
- PMAP_UNLOCK(pm);
- return (pa);
-}
-
-/*
- * Atomically extract and hold the physical page with the given
- * pmap and virtual address pair if that mapping permits the given
- * protection.
- */
-vm_page_t
-moea_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_prot_t prot)
-{
- struct pvo_entry *pvo;
- vm_page_t m;
-
- m = NULL;
- vm_page_lock_queues();
- PMAP_LOCK(pmap);
- pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
- if (pvo != NULL && (pvo->pvo_pte.pte_hi & PTE_VALID) &&
- ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_RW ||
- (prot & VM_PROT_WRITE) == 0)) {
- m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
- vm_page_hold(m);
- }
- vm_page_unlock_queues();
- PMAP_UNLOCK(pmap);
- return (m);
-}
-
-void
-moea_init(mmu_t mmu)
-{
-
- CTR0(KTR_PMAP, "moea_init");
-
- moea_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
- UMA_ZONE_VM | UMA_ZONE_NOFREE);
- moea_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
- UMA_ZONE_VM | UMA_ZONE_NOFREE);
- moea_initialized = TRUE;
-}
-
-boolean_t
-moea_is_modified(mmu_t mmu, vm_page_t m)
-{
-
- if ((m->flags & (PG_FICTITIOUS |PG_UNMANAGED)) != 0)
- return (FALSE);
-
- return (moea_query_bit(m, PTE_CHG));
-}
-
-void
-moea_clear_reference(mmu_t mmu, vm_page_t m)
-{
-
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
- return;
- moea_clear_bit(m, PTE_REF, NULL);
-}
-
-void
-moea_clear_modify(mmu_t mmu, vm_page_t m)
-{
-
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
- return;
- moea_clear_bit(m, PTE_CHG, NULL);
-}
-
-/*
- * Clear the write and modified bits in each of the given page's mappings.
- */
-void
-moea_remove_write(mmu_t mmu, vm_page_t m)
-{
- struct pvo_entry *pvo;
- struct pte *pt;
- pmap_t pmap;
- u_int lo;
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0 ||
- (m->flags & PG_WRITEABLE) == 0)
- return;
- lo = moea_attr_fetch(m);
- SYNC();
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- pmap = pvo->pvo_pmap;
- PMAP_LOCK(pmap);
- if ((pvo->pvo_pte.pte_lo & PTE_PP) != PTE_BR) {
- pt = moea_pvo_to_pte(pvo, -1);
- pvo->pvo_pte.pte_lo &= ~PTE_PP;
- pvo->pvo_pte.pte_lo |= PTE_BR;
- if (pt != NULL) {
- moea_pte_synch(pt, &pvo->pvo_pte);
- lo |= pvo->pvo_pte.pte_lo;
- pvo->pvo_pte.pte_lo &= ~PTE_CHG;
- moea_pte_change(pt, &pvo->pvo_pte,
- pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- }
- }
- PMAP_UNLOCK(pmap);
- }
- if ((lo & PTE_CHG) != 0) {
- moea_attr_clear(m, PTE_CHG);
- vm_page_dirty(m);
- }
- vm_page_flag_clear(m, PG_WRITEABLE);
-}
-
-/*
- * moea_ts_referenced:
- *
- * Return a count of reference bits for a page, clearing those bits.
- * It is not necessary for every reference bit to be cleared, but it
- * is necessary that 0 only be returned when there are truly no
- * reference bits set.
- *
- * XXX: The exact number of bits to check and clear is a matter that
- * should be tested and standardized at some point in the future for
- * optimal aging of shared pages.
- */
-boolean_t
-moea_ts_referenced(mmu_t mmu, vm_page_t m)
-{
- int count;
-
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
- return (0);
-
- count = moea_clear_bit(m, PTE_REF, NULL);
-
- return (count);
-}
-
-/*
- * Map a wired page into kernel virtual address space.
- */
-void
-moea_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
-{
- u_int pte_lo;
- int error;
- int i;
-
-#if 0
- if (va < VM_MIN_KERNEL_ADDRESS)
- panic("moea_kenter: attempt to enter non-kernel address %#x",
- va);
-#endif
-
- pte_lo = PTE_I | PTE_G;
- for (i = 0; i < pregions_sz; i++) {
- if ((pa >= pregions[i].mr_start) &&
- (pa < (pregions[i].mr_start + pregions[i].mr_size))) {
- pte_lo &= ~(PTE_I | PTE_G);
- break;
- }
- }
-
- PMAP_LOCK(kernel_pmap);
- error = moea_pvo_enter(kernel_pmap, moea_upvo_zone,
- &moea_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED);
-
- if (error != 0 && error != ENOENT)
- panic("moea_kenter: failed to enter va %#x pa %#x: %d", va,
- pa, error);
-
- /*
- * Flush the real memory from the instruction cache.
- */
- if ((pte_lo & (PTE_I | PTE_G)) == 0) {
- moea_syncicache(pa, PAGE_SIZE);
- }
- PMAP_UNLOCK(kernel_pmap);
-}
-
-/*
- * Extract the physical page address associated with the given kernel virtual
- * address.
- */
-vm_offset_t
-moea_kextract(mmu_t mmu, vm_offset_t va)
-{
- struct pvo_entry *pvo;
- vm_paddr_t pa;
-
-#ifdef UMA_MD_SMALL_ALLOC
- /*
- * Allow direct mappings
- */
- if (va < VM_MIN_KERNEL_ADDRESS) {
- return (va);
- }
-#endif
-
- PMAP_LOCK(kernel_pmap);
- pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
- KASSERT(pvo != NULL, ("moea_kextract: no addr found"));
- pa = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
- PMAP_UNLOCK(kernel_pmap);
- return (pa);
-}
-
-/*
- * Remove a wired page from kernel virtual address space.
- */
-void
-moea_kremove(mmu_t mmu, vm_offset_t va)
-{
-
- moea_remove(mmu, kernel_pmap, va, va + PAGE_SIZE);
-}
-
-/*
- * Map a range of physical addresses into kernel virtual address space.
- *
- * The value passed in *virt is a suggested virtual address for the mapping.
- * Architectures which can support a direct-mapped physical to virtual region
- * can return the appropriate address within that region, leaving '*virt'
- * unchanged. We cannot and therefore do not; *virt is updated with the
- * first usable address after the mapped region.
- */
-vm_offset_t
-moea_map(mmu_t mmu, vm_offset_t *virt, vm_offset_t pa_start,
- vm_offset_t pa_end, int prot)
-{
- vm_offset_t sva, va;
-
- sva = *virt;
- va = sva;
- for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
- moea_kenter(mmu, va, pa_start);
- *virt = va;
- return (sva);
-}
-
-/*
- * Returns true if the pmap's pv is one of the first
- * 16 pvs linked to from this page. This count may
- * be changed upwards or downwards in the future; it
- * is only necessary that true be returned for a small
- * subset of pmaps for proper page aging.
- */
-boolean_t
-moea_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m)
-{
- int loops;
- struct pvo_entry *pvo;
-
- if (!moea_initialized || (m->flags & PG_FICTITIOUS))
- return FALSE;
-
- loops = 0;
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- if (pvo->pvo_pmap == pmap)
- return (TRUE);
- if (++loops >= 16)
- break;
- }
-
- return (FALSE);
-}
-
-/*
- * Return the number of managed mappings to the given physical page
- * that are wired.
- */
-int
-moea_page_wired_mappings(mmu_t mmu, vm_page_t m)
-{
- struct pvo_entry *pvo;
- int count;
-
- count = 0;
- if (!moea_initialized || (m->flags & PG_FICTITIOUS) != 0)
- return (count);
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink)
- if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
- count++;
- return (count);
-}
-
-static u_int moea_vsidcontext;
-
-void
-moea_pinit(mmu_t mmu, pmap_t pmap)
-{
- int i, mask;
- u_int entropy;
-
- KASSERT((int)pmap < VM_MIN_KERNEL_ADDRESS, ("moea_pinit: virt pmap"));
- PMAP_LOCK_INIT(pmap);
-
- entropy = 0;
- __asm __volatile("mftb %0" : "=r"(entropy));
-
- /*
- * Allocate some segment registers for this pmap.
- */
- for (i = 0; i < NPMAPS; i += VSID_NBPW) {
- u_int hash, n;
-
- /*
- * Create a new value by mutiplying by a prime and adding in
- * entropy from the timebase register. This is to make the
- * VSID more random so that the PT hash function collides
- * less often. (Note that the prime casues gcc to do shifts
- * instead of a multiply.)
- */
- moea_vsidcontext = (moea_vsidcontext * 0x1105) + entropy;
- hash = moea_vsidcontext & (NPMAPS - 1);
- if (hash == 0) /* 0 is special, avoid it */
- continue;
- n = hash >> 5;
- mask = 1 << (hash & (VSID_NBPW - 1));
- hash = (moea_vsidcontext & 0xfffff);
- if (moea_vsid_bitmap[n] & mask) { /* collision? */
- /* anything free in this bucket? */
- if (moea_vsid_bitmap[n] == 0xffffffff) {
- entropy = (moea_vsidcontext >> 20);
- continue;
- }
- i = ffs(~moea_vsid_bitmap[i]) - 1;
- mask = 1 << i;
- hash &= 0xfffff & ~(VSID_NBPW - 1);
- hash |= i;
- }
- moea_vsid_bitmap[n] |= mask;
- for (i = 0; i < 16; i++)
- pmap->pm_sr[i] = VSID_MAKE(i, hash);
- return;
- }
-
- panic("moea_pinit: out of segments");
-}
-
-/*
- * Initialize the pmap associated with process 0.
- */
-void
-moea_pinit0(mmu_t mmu, pmap_t pm)
-{
-
- moea_pinit(mmu, pm);
- bzero(&pm->pm_stats, sizeof(pm->pm_stats));
-}
-
-/*
- * Set the physical protection on the specified range of this map as requested.
- */
-void
-moea_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
- vm_prot_t prot)
-{
- struct pvo_entry *pvo;
- struct pte *pt;
- int pteidx;
-
- CTR4(KTR_PMAP, "moea_protect: pm=%p sva=%#x eva=%#x prot=%#x", pm, sva,
- eva, prot);
-
-
- KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
- ("moea_protect: non current pmap"));
-
- if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
- moea_remove(mmu, pm, sva, eva);
- return;
- }
-
- vm_page_lock_queues();
- PMAP_LOCK(pm);
- for (; sva < eva; sva += PAGE_SIZE) {
- pvo = moea_pvo_find_va(pm, sva, &pteidx);
- if (pvo == NULL)
- continue;
-
- if ((prot & VM_PROT_EXECUTE) == 0)
- pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
-
- /*
- * Grab the PTE pointer before we diddle with the cached PTE
- * copy.
- */
- pt = moea_pvo_to_pte(pvo, pteidx);
- /*
- * Change the protection of the page.
- */
- pvo->pvo_pte.pte_lo &= ~PTE_PP;
- pvo->pvo_pte.pte_lo |= PTE_BR;
-
- /*
- * If the PVO is in the page table, update that pte as well.
- */
- if (pt != NULL) {
- moea_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- }
- }
- vm_page_unlock_queues();
- PMAP_UNLOCK(pm);
-}
-
-/*
- * Map a list of wired pages into kernel virtual address space. This is
- * intended for temporary mappings which do not need page modification or
- * references recorded. Existing mappings in the region are overwritten.
- */
-void
-moea_qenter(mmu_t mmu, vm_offset_t sva, vm_page_t *m, int count)
-{
- vm_offset_t va;
-
- va = sva;
- while (count-- > 0) {
- moea_kenter(mmu, va, VM_PAGE_TO_PHYS(*m));
- va += PAGE_SIZE;
- m++;
- }
-}
-
-/*
- * Remove page mappings from kernel virtual address space. Intended for
- * temporary mappings entered by moea_qenter.
- */
-void
-moea_qremove(mmu_t mmu, vm_offset_t sva, int count)
-{
- vm_offset_t va;
-
- va = sva;
- while (count-- > 0) {
- moea_kremove(mmu, va);
- va += PAGE_SIZE;
- }
-}
-
-void
-moea_release(mmu_t mmu, pmap_t pmap)
-{
- int idx, mask;
-
- /*
- * Free segment register's VSID
- */
- if (pmap->pm_sr[0] == 0)
- panic("moea_release");
-
- idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
- mask = 1 << (idx % VSID_NBPW);
- idx /= VSID_NBPW;
- moea_vsid_bitmap[idx] &= ~mask;
- PMAP_LOCK_DESTROY(pmap);
-}
-
-/*
- * Remove the given range of addresses from the specified map.
- */
-void
-moea_remove(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva)
-{
- struct pvo_entry *pvo;
- int pteidx;
-
- vm_page_lock_queues();
- PMAP_LOCK(pm);
- for (; sva < eva; sva += PAGE_SIZE) {
- pvo = moea_pvo_find_va(pm, sva, &pteidx);
- if (pvo != NULL) {
- moea_pvo_remove(pvo, pteidx);
- }
- }
- PMAP_UNLOCK(pm);
- vm_page_unlock_queues();
-}
-
-/*
- * Remove physical page from all pmaps in which it resides. moea_pvo_remove()
- * will reflect changes in pte's back to the vm_page.
- */
-void
-moea_remove_all(mmu_t mmu, vm_page_t m)
-{
- struct pvo_head *pvo_head;
- struct pvo_entry *pvo, *next_pvo;
- pmap_t pmap;
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
-
- pvo_head = vm_page_to_pvoh(m);
- for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
- next_pvo = LIST_NEXT(pvo, pvo_vlink);
-
- MOEA_PVO_CHECK(pvo); /* sanity check */
- pmap = pvo->pvo_pmap;
- PMAP_LOCK(pmap);
- moea_pvo_remove(pvo, -1);
- PMAP_UNLOCK(pmap);
- }
- vm_page_flag_clear(m, PG_WRITEABLE);
-}
-
-/*
- * Allocate a physical page of memory directly from the phys_avail map.
- * Can only be called from moea_bootstrap before avail start and end are
- * calculated.
- */
-static vm_offset_t
-moea_bootstrap_alloc(vm_size_t size, u_int align)
-{
- vm_offset_t s, e;
- int i, j;
-
- size = round_page(size);
- for (i = 0; phys_avail[i + 1] != 0; i += 2) {
- if (align != 0)
- s = (phys_avail[i] + align - 1) & ~(align - 1);
- else
- s = phys_avail[i];
- e = s + size;
-
- if (s < phys_avail[i] || e > phys_avail[i + 1])
- continue;
-
- if (s == phys_avail[i]) {
- phys_avail[i] += size;
- } else if (e == phys_avail[i + 1]) {
- phys_avail[i + 1] -= size;
- } else {
- for (j = phys_avail_count * 2; j > i; j -= 2) {
- phys_avail[j] = phys_avail[j - 2];
- phys_avail[j + 1] = phys_avail[j - 1];
- }
-
- phys_avail[i + 3] = phys_avail[i + 1];
- phys_avail[i + 1] = s;
- phys_avail[i + 2] = e;
- phys_avail_count++;
- }
-
- return (s);
- }
- panic("moea_bootstrap_alloc: could not allocate memory");
-}
-
-/*
- * Return an unmapped pvo for a kernel virtual address.
- * Used by pmap functions that operate on physical pages.
- */
-static struct pvo_entry *
-moea_rkva_alloc(mmu_t mmu)
-{
- struct pvo_entry *pvo;
- struct pte *pt;
- vm_offset_t kva;
- int pteidx;
-
- if (moea_rkva_count == 0)
- panic("moea_rkva_alloc: no more reserved KVAs");
-
- kva = moea_rkva_start + (PAGE_SIZE * --moea_rkva_count);
- moea_kenter(mmu, kva, 0);
-
- pvo = moea_pvo_find_va(kernel_pmap, kva, &pteidx);
-
- if (pvo == NULL)
- panic("moea_kva_alloc: moea_pvo_find_va failed");
-
- pt = moea_pvo_to_pte(pvo, pteidx);
-
- if (pt == NULL)
- panic("moea_kva_alloc: moea_pvo_to_pte failed");
-
- moea_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- PVO_PTEGIDX_CLR(pvo);
-
- moea_pte_overflow++;
-
- return (pvo);
-}
-
-static void
-moea_pa_map(struct pvo_entry *pvo, vm_offset_t pa, struct pte *saved_pt,
- int *depth_p)
-{
- struct pte *pt;
-
- /*
- * If this pvo already has a valid pte, we need to save it so it can
- * be restored later. We then just reload the new PTE over the old
- * slot.
- */
- if (saved_pt != NULL) {
- pt = moea_pvo_to_pte(pvo, -1);
-
- if (pt != NULL) {
- moea_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- PVO_PTEGIDX_CLR(pvo);
- moea_pte_overflow++;
- }
-
- *saved_pt = pvo->pvo_pte;
-
- pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
- }
-
- pvo->pvo_pte.pte_lo |= pa;
-
- if (!moea_pte_spill(pvo->pvo_vaddr))
- panic("moea_pa_map: could not spill pvo %p", pvo);
-
- if (depth_p != NULL)
- (*depth_p)++;
-}
-
-static void
-moea_pa_unmap(struct pvo_entry *pvo, struct pte *saved_pt, int *depth_p)
-{
- struct pte *pt;
-
- pt = moea_pvo_to_pte(pvo, -1);
-
- if (pt != NULL) {
- moea_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- PVO_PTEGIDX_CLR(pvo);
- moea_pte_overflow++;
- }
-
- pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
-
- /*
- * If there is a saved PTE and it's valid, restore it and return.
- */
- if (saved_pt != NULL && (saved_pt->pte_lo & PTE_RPGN) != 0) {
- if (depth_p != NULL && --(*depth_p) == 0)
- panic("moea_pa_unmap: restoring but depth == 0");
-
- pvo->pvo_pte = *saved_pt;
-
- if (!moea_pte_spill(pvo->pvo_vaddr))
- panic("moea_pa_unmap: could not spill pvo %p", pvo);
- }
-}
-
-static void
-moea_syncicache(vm_offset_t pa, vm_size_t len)
-{
- __syncicache((void *)pa, len);
-}
-
-static void
-tlbia(void)
-{
- caddr_t i;
-
- SYNC();
- for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
- TLBIE(i);
- EIEIO();
- }
- TLBSYNC();
- SYNC();
-}
-
-static int
-moea_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
- vm_offset_t va, vm_offset_t pa, u_int pte_lo, int flags)
-{
- struct pvo_entry *pvo;
- u_int sr;
- int first;
- u_int ptegidx;
- int i;
- int bootstrap;
-
- moea_pvo_enter_calls++;
- first = 0;
- bootstrap = 0;
-
- /*
- * Compute the PTE Group index.
- */
- va &= ~ADDR_POFF;
- sr = va_to_sr(pm->pm_sr, va);
- ptegidx = va_to_pteg(sr, va);
-
- /*
- * Remove any existing mapping for this page. Reuse the pvo entry if
- * there is a mapping.
- */
- mtx_lock(&moea_table_mutex);
- LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
- if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
- if ((pvo->pvo_pte.pte_lo & PTE_RPGN) == pa &&
- (pvo->pvo_pte.pte_lo & PTE_PP) ==
- (pte_lo & PTE_PP)) {
- mtx_unlock(&moea_table_mutex);
- return (0);
- }
- moea_pvo_remove(pvo, -1);
- break;
- }
- }
-
- /*
- * If we aren't overwriting a mapping, try to allocate.
- */
- if (moea_initialized) {
- pvo = uma_zalloc(zone, M_NOWAIT);
- } else {
- if (moea_bpvo_pool_index >= BPVO_POOL_SIZE) {
- panic("moea_enter: bpvo pool exhausted, %d, %d, %d",
- moea_bpvo_pool_index, BPVO_POOL_SIZE,
- BPVO_POOL_SIZE * sizeof(struct pvo_entry));
- }
- pvo = &moea_bpvo_pool[moea_bpvo_pool_index];
- moea_bpvo_pool_index++;
- bootstrap = 1;
- }
-
- if (pvo == NULL) {
- mtx_unlock(&moea_table_mutex);
- return (ENOMEM);
- }
-
- moea_pvo_entries++;
- pvo->pvo_vaddr = va;
- pvo->pvo_pmap = pm;
- LIST_INSERT_HEAD(&moea_pvo_table[ptegidx], pvo, pvo_olink);
- pvo->pvo_vaddr &= ~ADDR_POFF;
- if (flags & VM_PROT_EXECUTE)
- pvo->pvo_vaddr |= PVO_EXECUTABLE;
- if (flags & PVO_WIRED)
- pvo->pvo_vaddr |= PVO_WIRED;
- if (pvo_head != &moea_pvo_kunmanaged)
- pvo->pvo_vaddr |= PVO_MANAGED;
- if (bootstrap)
- pvo->pvo_vaddr |= PVO_BOOTSTRAP;
- if (flags & PVO_FAKE)
- pvo->pvo_vaddr |= PVO_FAKE;
-
- moea_pte_create(&pvo->pvo_pte, sr, va, pa | pte_lo);
-
- /*
- * Remember if the list was empty and therefore will be the first
- * item.
- */
- if (LIST_FIRST(pvo_head) == NULL)
- first = 1;
- LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
-
- if (pvo->pvo_pte.pte_lo & PVO_WIRED)
- pm->pm_stats.wired_count++;
- pm->pm_stats.resident_count++;
-
- /*
- * We hope this succeeds but it isn't required.
- */
- i = moea_pte_insert(ptegidx, &pvo->pvo_pte);
- if (i >= 0) {
- PVO_PTEGIDX_SET(pvo, i);
- } else {
- panic("moea_pvo_enter: overflow");
- moea_pte_overflow++;
- }
- mtx_unlock(&moea_table_mutex);
-
- return (first ? ENOENT : 0);
-}
-
-static void
-moea_pvo_remove(struct pvo_entry *pvo, int pteidx)
-{
- struct pte *pt;
-
- /*
- * If there is an active pte entry, we need to deactivate it (and
- * save the ref & cfg bits).
- */
- pt = moea_pvo_to_pte(pvo, pteidx);
- if (pt != NULL) {
- moea_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
- mtx_unlock(&moea_table_mutex);
- PVO_PTEGIDX_CLR(pvo);
- } else {
- moea_pte_overflow--;
- }
-
- /*
- * Update our statistics.
- */
- pvo->pvo_pmap->pm_stats.resident_count--;
- if (pvo->pvo_pte.pte_lo & PVO_WIRED)
- pvo->pvo_pmap->pm_stats.wired_count--;
-
- /*
- * Save the REF/CHG bits into their cache if the page is managed.
- */
- if ((pvo->pvo_vaddr & (PVO_MANAGED|PVO_FAKE)) == PVO_MANAGED) {
- struct vm_page *pg;
-
- pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
- if (pg != NULL) {
- moea_attr_save(pg, pvo->pvo_pte.pte_lo &
- (PTE_REF | PTE_CHG));
- }
- }
-
- /*
- * Remove this PVO from the PV list.
- */
- LIST_REMOVE(pvo, pvo_vlink);
-
- /*
- * Remove this from the overflow list and return it to the pool
- * if we aren't going to reuse it.
- */
- LIST_REMOVE(pvo, pvo_olink);
- if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
- uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? moea_mpvo_zone :
- moea_upvo_zone, pvo);
- moea_pvo_entries--;
- moea_pvo_remove_calls++;
-}
-
-static __inline int
-moea_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
-{
- int pteidx;
-
- /*
- * We can find the actual pte entry without searching by grabbing
- * the PTEG index from 3 unused bits in pte_lo[11:9] and by
- * noticing the HID bit.
- */
- pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
- if (pvo->pvo_pte.pte_hi & PTE_HID)
- pteidx ^= moea_pteg_mask * 8;
-
- return (pteidx);
-}
-
-static struct pvo_entry *
-moea_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p)
-{
- struct pvo_entry *pvo;
- int ptegidx;
- u_int sr;
-
- va &= ~ADDR_POFF;
- sr = va_to_sr(pm->pm_sr, va);
- ptegidx = va_to_pteg(sr, va);
-
- mtx_lock(&moea_table_mutex);
- LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
- if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
- if (pteidx_p)
- *pteidx_p = moea_pvo_pte_index(pvo, ptegidx);
- break;
- }
- }
- mtx_unlock(&moea_table_mutex);
-
- return (pvo);
-}
-
-static struct pte *
-moea_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
-{
- struct pte *pt;
-
- /*
- * If we haven't been supplied the ptegidx, calculate it.
- */
- if (pteidx == -1) {
- int ptegidx;
- u_int sr;
-
- sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr);
- ptegidx = va_to_pteg(sr, pvo->pvo_vaddr);
- pteidx = moea_pvo_pte_index(pvo, ptegidx);
- }
-
- pt = &moea_pteg_table[pteidx >> 3].pt[pteidx & 7];
- mtx_lock(&moea_table_mutex);
-
- if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
- panic("moea_pvo_to_pte: pvo %p has valid pte in pvo but no "
- "valid pte index", pvo);
- }
-
- if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
- panic("moea_pvo_to_pte: pvo %p has valid pte index in pvo "
- "pvo but no valid pte", pvo);
- }
-
- if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
- if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
- panic("moea_pvo_to_pte: pvo %p has valid pte in "
- "moea_pteg_table %p but invalid in pvo", pvo, pt);
- }
-
- if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF))
- != 0) {
- panic("moea_pvo_to_pte: pvo %p pte does not match "
- "pte %p in moea_pteg_table", pvo, pt);
- }
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
- return (pt);
- }
-
- if (pvo->pvo_pte.pte_hi & PTE_VALID) {
- panic("moea_pvo_to_pte: pvo %p has invalid pte %p in "
- "moea_pteg_table but valid in pvo", pvo, pt);
- }
-
- mtx_unlock(&moea_table_mutex);
- return (NULL);
-}
-
-/*
- * XXX: THIS STUFF SHOULD BE IN pte.c?
- */
-int
-moea_pte_spill(vm_offset_t addr)
-{
- struct pvo_entry *source_pvo, *victim_pvo;
- struct pvo_entry *pvo;
- int ptegidx, i, j;
- u_int sr;
- struct pteg *pteg;
- struct pte *pt;
-
- moea_pte_spills++;
-
- sr = mfsrin(addr);
- ptegidx = va_to_pteg(sr, addr);
-
- /*
- * Have to substitute some entry. Use the primary hash for this.
- * Use low bits of timebase as random generator.
- */
- pteg = &moea_pteg_table[ptegidx];
- mtx_lock(&moea_table_mutex);
- __asm __volatile("mftb %0" : "=r"(i));
- i &= 7;
- pt = &pteg->pt[i];
-
- source_pvo = NULL;
- victim_pvo = NULL;
- LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
- /*
- * We need to find a pvo entry for this address.
- */
- MOEA_PVO_CHECK(pvo);
- if (source_pvo == NULL &&
- moea_pte_match(&pvo->pvo_pte, sr, addr,
- pvo->pvo_pte.pte_hi & PTE_HID)) {
- /*
- * Now found an entry to be spilled into the pteg.
- * The PTE is now valid, so we know it's active.
- */
- j = moea_pte_insert(ptegidx, &pvo->pvo_pte);
-
- if (j >= 0) {
- PVO_PTEGIDX_SET(pvo, j);
- moea_pte_overflow--;
- MOEA_PVO_CHECK(pvo);
- mtx_unlock(&moea_table_mutex);
- return (1);
- }
-
- source_pvo = pvo;
-
- if (victim_pvo != NULL)
- break;
- }
-
- /*
- * We also need the pvo entry of the victim we are replacing
- * so save the R & C bits of the PTE.
- */
- if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
- moea_pte_compare(pt, &pvo->pvo_pte)) {
- victim_pvo = pvo;
- if (source_pvo != NULL)
- break;
- }
- }
-
- if (source_pvo == NULL) {
- mtx_unlock(&moea_table_mutex);
- return (0);
- }
-
- if (victim_pvo == NULL) {
- if ((pt->pte_hi & PTE_HID) == 0)
- panic("moea_pte_spill: victim p-pte (%p) has no pvo"
- "entry", pt);
-
- /*
- * If this is a secondary PTE, we need to search it's primary
- * pvo bucket for the matching PVO.
- */
- LIST_FOREACH(pvo, &moea_pvo_table[ptegidx ^ moea_pteg_mask],
- pvo_olink) {
- MOEA_PVO_CHECK(pvo);
- /*
- * We also need the pvo entry of the victim we are
- * replacing so save the R & C bits of the PTE.
- */
- if (moea_pte_compare(pt, &pvo->pvo_pte)) {
- victim_pvo = pvo;
- break;
- }
- }
-
- if (victim_pvo == NULL)
- panic("moea_pte_spill: victim s-pte (%p) has no pvo"
- "entry", pt);
- }
-
- /*
- * We are invalidating the TLB entry for the EA we are replacing even
- * though it's valid. If we don't, we lose any ref/chg bit changes
- * contained in the TLB entry.
- */
- source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
-
- moea_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
- moea_pte_set(pt, &source_pvo->pvo_pte);
-
- PVO_PTEGIDX_CLR(victim_pvo);
- PVO_PTEGIDX_SET(source_pvo, i);
- moea_pte_replacements++;
-
- MOEA_PVO_CHECK(victim_pvo);
- MOEA_PVO_CHECK(source_pvo);
-
- mtx_unlock(&moea_table_mutex);
- return (1);
-}
-
-static int
-moea_pte_insert(u_int ptegidx, struct pte *pvo_pt)
-{
- struct pte *pt;
- int i;
-
- mtx_assert(&moea_table_mutex, MA_OWNED);
-
- /*
- * First try primary hash.
- */
- for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
- if ((pt->pte_hi & PTE_VALID) == 0) {
- pvo_pt->pte_hi &= ~PTE_HID;
- moea_pte_set(pt, pvo_pt);
- return (i);
- }
- }
-
- /*
- * Now try secondary hash.
- */
- ptegidx ^= moea_pteg_mask;
-
- for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
- if ((pt->pte_hi & PTE_VALID) == 0) {
- pvo_pt->pte_hi |= PTE_HID;
- moea_pte_set(pt, pvo_pt);
- return (i);
- }
- }
-
- panic("moea_pte_insert: overflow");
- return (-1);
-}
-
-static boolean_t
-moea_query_bit(vm_page_t m, int ptebit)
-{
- struct pvo_entry *pvo;
- struct pte *pt;
-
-#if 0
- if (moea_attr_fetch(m) & ptebit)
- return (TRUE);
-#endif
-
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- MOEA_PVO_CHECK(pvo); /* sanity check */
-
- /*
- * See if we saved the bit off. If so, cache it and return
- * success.
- */
- if (pvo->pvo_pte.pte_lo & ptebit) {
- moea_attr_save(m, ptebit);
- MOEA_PVO_CHECK(pvo); /* sanity check */
- return (TRUE);
- }
- }
-
- /*
- * No luck, now go through the hard part of looking at the PTEs
- * themselves. Sync so that any pending REF/CHG bits are flushed to
- * the PTEs.
- */
- SYNC();
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- MOEA_PVO_CHECK(pvo); /* sanity check */
-
- /*
- * See if this pvo has a valid PTE. if so, fetch the
- * REF/CHG bits from the valid PTE. If the appropriate
- * ptebit is set, cache it and return success.
- */
- pt = moea_pvo_to_pte(pvo, -1);
- if (pt != NULL) {
- moea_pte_synch(pt, &pvo->pvo_pte);
- mtx_unlock(&moea_table_mutex);
- if (pvo->pvo_pte.pte_lo & ptebit) {
- moea_attr_save(m, ptebit);
- MOEA_PVO_CHECK(pvo); /* sanity check */
- return (TRUE);
- }
- }
- }
-
- return (FALSE);
-}
-
-static u_int
-moea_clear_bit(vm_page_t m, int ptebit, int *origbit)
-{
- u_int count;
- struct pvo_entry *pvo;
- struct pte *pt;
- int rv;
-
- /*
- * Clear the cached value.
- */
- rv = moea_attr_fetch(m);
- moea_attr_clear(m, ptebit);
-
- /*
- * Sync so that any pending REF/CHG bits are flushed to the PTEs (so
- * we can reset the right ones). note that since the pvo entries and
- * list heads are accessed via BAT0 and are never placed in the page
- * table, we don't have to worry about further accesses setting the
- * REF/CHG bits.
- */
- SYNC();
-
- /*
- * For each pvo entry, clear the pvo's ptebit. If this pvo has a
- * valid pte clear the ptebit from the valid pte.
- */
- count = 0;
- LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
- MOEA_PVO_CHECK(pvo); /* sanity check */
- pt = moea_pvo_to_pte(pvo, -1);
- if (pt != NULL) {
- moea_pte_synch(pt, &pvo->pvo_pte);
- if (pvo->pvo_pte.pte_lo & ptebit) {
- count++;
- moea_pte_clear(pt, PVO_VADDR(pvo), ptebit);
- }
- mtx_unlock(&moea_table_mutex);
- }
- rv |= pvo->pvo_pte.pte_lo;
- pvo->pvo_pte.pte_lo &= ~ptebit;
- MOEA_PVO_CHECK(pvo); /* sanity check */
- }
-
- if (origbit != NULL) {
- *origbit = rv;
- }
-
- return (count);
-}
-
-/*
- * Return true if the physical range is encompassed by the battable[idx]
- */
-static int
-moea_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
-{
- u_int prot;
- u_int32_t start;
- u_int32_t end;
- u_int32_t bat_ble;
-
- /*
- * Return immediately if not a valid mapping
- */
- if (!battable[idx].batu & BAT_Vs)
- return (EINVAL);
-
- /*
- * The BAT entry must be cache-inhibited, guarded, and r/w
- * so it can function as an i/o page
- */
- prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
- if (prot != (BAT_I|BAT_G|BAT_PP_RW))
- return (EPERM);
-
- /*
- * The address should be within the BAT range. Assume that the
- * start address in the BAT has the correct alignment (thus
- * not requiring masking)
- */
- start = battable[idx].batl & BAT_PBS;
- bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03;
- end = start | (bat_ble << 15) | 0x7fff;
-
- if ((pa < start) || ((pa + size) > end))
- return (ERANGE);
-
- return (0);
-}
-
-boolean_t
-moea_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
-{
- int i;
-
- /*
- * This currently does not work for entries that
- * overlap 256M BAT segments.
- */
-
- for(i = 0; i < 16; i++)
- if (moea_bat_mapped(i, pa, size) == 0)
- return (0);
-
- return (EFAULT);
-}
-
-boolean_t
-moea_page_executable(mmu_t mmu, vm_page_t pg)
-{
- return ((moea_attr_fetch(pg) & PTE_EXEC) == PTE_EXEC);
-}
-
-/*
- * Map a set of physical memory pages into the kernel virtual
- * address space. Return a pointer to where it is mapped. This
- * routine is intended to be used for mapping device memory,
- * NOT real memory.
- */
-void *
-moea_mapdev(mmu_t mmu, vm_offset_t pa, vm_size_t size)
-{
- vm_offset_t va, tmpva, ppa, offset;
- int i;
-
- ppa = trunc_page(pa);
- offset = pa & PAGE_MASK;
- size = roundup(offset + size, PAGE_SIZE);
-
- GIANT_REQUIRED;
-
- /*
- * If the physical address lies within a valid BAT table entry,
- * return the 1:1 mapping. This currently doesn't work
- * for regions that overlap 256M BAT segments.
- */
- for (i = 0; i < 16; i++) {
- if (moea_bat_mapped(i, pa, size) == 0)
- return ((void *) pa);
- }
-
- va = kmem_alloc_nofault(kernel_map, size);
- if (!va)
- panic("moea_mapdev: Couldn't alloc kernel virtual memory");
-
- for (tmpva = va; size > 0;) {
- moea_kenter(mmu, tmpva, ppa);
- TLBIE(tmpva); /* XXX or should it be invalidate-all ? */
- size -= PAGE_SIZE;
- tmpva += PAGE_SIZE;
- ppa += PAGE_SIZE;
- }
-
- return ((void *)(va + offset));
-}
-
-void
-moea_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
-{
- vm_offset_t base, offset;
-
- /*
- * If this is outside kernel virtual space, then it's a
- * battable entry and doesn't require unmapping
- */
- if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)) {
- base = trunc_page(va);
- offset = va & PAGE_MASK;
- size = roundup(offset + size, PAGE_SIZE);
- kmem_free(kernel_map, base, size);
- }
-}
diff --git a/sys/powerpc/powerpc/nexus.c b/sys/powerpc/powerpc/nexus.c
deleted file mode 100644
index e31ef61..0000000
--- a/sys/powerpc/powerpc/nexus.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*-
- * Copyright 1998 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that both the above copyright notice and this
- * permission notice appear in all copies, that both the above
- * copyright notice and this permission notice appear in all
- * supporting documentation, and that the name of M.I.T. not be used
- * in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. M.I.T. makes
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
- * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
- * SHALL M.I.T. 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.
- */
-/*-
- * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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: FreeBSD: src/sys/i386/i386/nexus.c,v 1.43 2001/02/09
- *
- * $FreeBSD$
- */
-#include "opt_psim.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/cons.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-
-#include <dev/ofw/openfirm.h>
-
-#include <machine/bus.h>
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <machine/nexusvar.h>
-#include <machine/resource.h>
-
-#include <sys/rman.h>
-
-#include "ofw_bus_if.h"
-#include "pic_if.h"
-
-/*
- * The nexus (which is a pseudo-bus actually) iterates over the nodes that
- * exist in Open Firmware and adds them as devices to this bus so that drivers
- * can be attached to them.
- *
- * Maybe this code should get into dev/ofw to some extent, as some of it should
- * work for all Open Firmware based machines...
- */
-
-static MALLOC_DEFINE(M_NEXUS, "nexus", "nexus device information");
-
-struct nexus_devinfo {
- phandle_t ndi_node;
- /* Some common properties. */
- const char *ndi_name;
- const char *ndi_device_type;
- const char *ndi_compatible;
-};
-
-struct nexus_softc {
- struct rman sc_rman;
-};
-
-/*
- * Device interface
- */
-static int nexus_probe(device_t);
-static void nexus_probe_nomatch(device_t, device_t);
-
-/*
- * Bus interface
- */
-static device_t nexus_add_child(device_t, int, const char *, int);
-static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
-static int nexus_write_ivar(device_t, device_t, int, uintptr_t);
-static int nexus_setup_intr(device_t, device_t, struct resource *, int,
- driver_filter_t *, driver_intr_t *, void *, void **);
-static int nexus_teardown_intr(device_t, device_t, struct resource *,
- void *);
-static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
- u_long, u_long, u_long, u_int);
-static int nexus_activate_resource(device_t, device_t, int, int,
- struct resource *);
-static int nexus_deactivate_resource(device_t, device_t, int, int,
- struct resource *);
-static int nexus_release_resource(device_t, device_t, int, int,
- struct resource *);
-
-static phandle_t nexus_ofw_get_node(device_t, device_t);
-static const char *nexus_ofw_get_name(device_t, device_t);
-static const char *nexus_ofw_get_type(device_t, device_t);
-static const char *nexus_ofw_get_compat(device_t, device_t);
-
-/*
- * Local routines
- */
-static device_t nexus_device_from_node(device_t, phandle_t);
-
-static device_method_t nexus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, bus_generic_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface. Resource management is business of the children... */
- DEVMETHOD(bus_add_child, nexus_add_child),
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch),
- DEVMETHOD(bus_read_ivar, nexus_read_ivar),
- DEVMETHOD(bus_write_ivar, nexus_write_ivar),
- DEVMETHOD(bus_setup_intr, nexus_setup_intr),
- DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
- DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
- DEVMETHOD(bus_activate_resource, nexus_activate_resource),
- DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
- DEVMETHOD(bus_release_resource, nexus_release_resource),
-
- /* OFW bus interface */
- DEVMETHOD(ofw_bus_get_node, nexus_ofw_get_node),
- DEVMETHOD(ofw_bus_get_name, nexus_ofw_get_name),
- DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type),
- DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat),
-
- { 0, 0 }
-};
-
-static driver_t nexus_driver = {
- "nexus",
- nexus_methods,
- sizeof(struct nexus_softc),
-};
-
-static devclass_t nexus_devclass;
-
-DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
-
-static int
-nexus_probe(device_t dev)
-{
- phandle_t root;
- phandle_t child;
- struct nexus_softc *sc;
- u_long start, end;
-
- if ((root = OF_peer(0)) == -1)
- panic("nexus_probe: OF_peer failed.");
-
- sc = device_get_softc(dev);
-
- start = 0;
- end = INTR_VECTORS - 1;
-
- sc->sc_rman.rm_start = start;
- sc->sc_rman.rm_end = end;
- sc->sc_rman.rm_type = RMAN_ARRAY;
- sc->sc_rman.rm_descr = "Interrupt request lines";
- if (rman_init(&sc->sc_rman) ||
- rman_manage_region(&sc->sc_rman, start, end))
- panic("nexus_probe IRQ rman");
-
- /*
- * Allow devices to identify
- */
- bus_generic_probe(dev);
-
- /*
- * Now walk the OFW tree to locate top-level devices
- */
- for (child = OF_child(root); child != 0; child = OF_peer(child)) {
- if (child == -1)
- panic("nexus_probe(): OF_child failed.");
- (void)nexus_device_from_node(dev, child);
-
- }
- device_set_desc(dev, "Open Firmware Nexus device");
- return (0);
-}
-
-static void
-nexus_probe_nomatch(device_t dev, device_t child)
-{
- char *name, *type;
-
- if (BUS_READ_IVAR(dev, child, NEXUS_IVAR_NAME,
- (uintptr_t *)&name) != 0 ||
- BUS_READ_IVAR(dev, child, NEXUS_IVAR_DEVICE_TYPE,
- (uintptr_t *)&type) != 0)
- return;
-
- if (type == NULL)
- type = "(unknown)";
-
- if (bootverbose)
- device_printf(dev, "<%s>, type %s (no driver attached)\n",
- name, type);
-}
-
-static device_t
-nexus_add_child(device_t dev, int order, const char *name, int unit)
-{
- device_t child;
- struct nexus_devinfo *dinfo;
-
- child = device_add_child_ordered(dev, order, name, unit);
- if (child == NULL)
- return (NULL);
-
- dinfo = malloc(sizeof(struct nexus_devinfo), M_NEXUS, M_NOWAIT|M_ZERO);
- if (dinfo == NULL)
- return (NULL);
-
- dinfo->ndi_node = -1;
- dinfo->ndi_name = name;
- device_set_ivars(child, dinfo);
-
- return (child);
-}
-
-
-static int
-nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(child)) == 0)
- return (ENOENT);
- switch (which) {
- case NEXUS_IVAR_NODE:
- *result = dinfo->ndi_node;
- break;
- case NEXUS_IVAR_NAME:
- *result = (uintptr_t)dinfo->ndi_name;
- break;
- case NEXUS_IVAR_DEVICE_TYPE:
- *result = (uintptr_t)dinfo->ndi_device_type;
- break;
- case NEXUS_IVAR_COMPATIBLE:
- *result = (uintptr_t)dinfo->ndi_compatible;
- break;
- default:
- return (ENOENT);
- }
- return 0;
-}
-
-static int
-nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(child)) == 0)
- return (ENOENT);
-
- switch (which) {
- case NEXUS_IVAR_NAME:
- return (EINVAL);
-
- /* Identified devices may want to set these */
- case NEXUS_IVAR_NODE:
- dinfo->ndi_node = (phandle_t)value;
- break;
-
- case NEXUS_IVAR_DEVICE_TYPE:
- dinfo->ndi_device_type = (char *)value;
- break;
-
- default:
- return (ENOENT);
- }
- return 0;
-}
-
-static int
-nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
-{
- driver_t *driver;
- int error;
-
- /* somebody tried to setup an irq that failed to allocate! */
- if (res == NULL)
- panic("nexus_setup_intr: NULL irq resource!");
-
- *cookiep = 0;
- if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
- flags |= INTR_EXCL;
-
- driver = device_get_driver(child);
-
- /*
- * We depend here on rman_activate_resource() being idempotent.
- */
- error = rman_activate_resource(res);
- if (error)
- return (error);
-
- error = powerpc_setup_intr(device_get_nameunit(child),
- rman_get_start(res), filter, ihand, arg, flags, cookiep);
-
- return (error);
-}
-
-static int
-nexus_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *cookie)
-{
-
- return (powerpc_teardown_intr(cookie));
-}
-
-/*
- * Allocate resources at the behest of a child. This only handles interrupts,
- * since I/O resources are handled by child busses.
- */
-static struct resource *
-nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- struct nexus_softc *sc;
- struct resource *rv;
-
- if (type != SYS_RES_IRQ) {
- device_printf(bus, "unknown resource request from %s\n",
- device_get_nameunit(child));
- return (NULL);
- }
-
- if (count == 0 || start + count - 1 != end) {
- device_printf(bus, "invalid IRQ allocation from %s\n",
- device_get_nameunit(child));
- return (NULL);
- }
-
- sc = device_get_softc(bus);
-
- rv = rman_reserve_resource(&sc->sc_rman, start, end, count,
- flags, child);
- if (rv == NULL) {
- device_printf(bus, "IRQ allocation failed for %s\n",
- device_get_nameunit(child));
- } else
- rman_set_rid(rv, *rid);
-
- return (rv);
-}
-
-static int
-nexus_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *res)
-{
-
- /* Not much to be done yet... */
- return (rman_activate_resource(res));
-}
-
-static int
-nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *res)
-{
-
- /* Not much to be done yet... */
- return (rman_deactivate_resource(res));
-}
-
-static int
-nexus_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *res)
-{
-
- if (type != SYS_RES_IRQ) {
- device_printf(bus, "unknown resource request from %s\n",
- device_get_nameunit(child));
- return (EINVAL);
- }
-
- return (rman_release_resource(res));
-}
-
-static device_t
-nexus_device_from_node(device_t parent, phandle_t node)
-{
- device_t cdev;
- struct nexus_devinfo *dinfo;
- char *name, *type, *compatible;
-
- OF_getprop_alloc(node, "name", 1, (void **)&name);
- OF_getprop_alloc(node, "device_type", 1, (void **)&type);
- OF_getprop_alloc(node, "compatible", 1, (void **)&compatible);
- cdev = device_add_child(parent, NULL, -1);
- if (cdev != NULL) {
- dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_WAITOK);
- dinfo->ndi_node = node;
- dinfo->ndi_name = name;
- dinfo->ndi_device_type = type;
- dinfo->ndi_compatible = compatible;
- device_set_ivars(cdev, dinfo);
- } else
- free(name, M_OFWPROP);
-
- return (cdev);
-}
-
-static const char *
-nexus_ofw_get_name(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_name);
-}
-
-static phandle_t
-nexus_ofw_get_node(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (0);
-
- return (dinfo->ndi_node);
-}
-
-static const char *
-nexus_ofw_get_type(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_device_type);
-}
-
-static const char *
-nexus_ofw_get_compat(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_compatible);
-}
diff --git a/sys/powerpc/powerpc/ofw_machdep.c b/sys/powerpc/powerpc/ofw_machdep.c
deleted file mode 100644
index d63236f..0000000
--- a/sys/powerpc/powerpc/ofw_machdep.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*-
- * Copyright (C) 1996 Wolfgang Solfrank.
- * Copyright (C) 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- *
- * $NetBSD: ofw_machdep.c,v 1.5 2000/05/23 13:25:43 tsubai Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/disk.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-
-#include <net/ethernet.h>
-
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_pci.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-
-#include <machine/bus.h>
-#include <machine/md_var.h>
-#include <machine/powerpc.h>
-#include <machine/ofw_machdep.h>
-#include <powerpc/ofw/ofw_pci.h>
-
-#define OFMEM_REGIONS 32
-static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
-static struct mem_region OFfree[OFMEM_REGIONS + 3];
-
-extern register_t ofmsr[5];
-extern struct pcpu __pcpu[MAXCPU];
-extern struct pmap ofw_pmap;
-static int (*ofwcall)(void *);
-
-/*
- * Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback.
- */
-register_t ofw_sprg0_save;
-
-static __inline void
-ofw_sprg_prepare(void)
-{
- /*
- * Assume that interrupt are disabled at this point, or
- * SPRG1-3 could be trashed
- */
- __asm __volatile("mfsprg0 %0\n\t"
- "mtsprg0 %1\n\t"
- "mtsprg1 %2\n\t"
- "mtsprg2 %3\n\t"
- "mtsprg3 %4\n\t"
- : "=&r"(ofw_sprg0_save)
- : "r"(ofmsr[1]),
- "r"(ofmsr[2]),
- "r"(ofmsr[3]),
- "r"(ofmsr[4]));
-}
-
-static __inline void
-ofw_sprg_restore(void)
-{
- /*
- * Note that SPRG1-3 contents are irrelevant. They are scratch
- * registers used in the early portion of trap handling when
- * interrupts are disabled.
- *
- * PCPU data cannot be used until this routine is called !
- */
- __asm __volatile("mtsprg0 %0" :: "r"(ofw_sprg0_save));
-}
-
-/*
- * Memory region utilities: determine if two regions overlap,
- * and merge two overlapping regions into one
- */
-static int
-memr_overlap(struct mem_region *r1, struct mem_region *r2)
-{
- if ((r1->mr_start + r1->mr_size) < r2->mr_start ||
- (r2->mr_start + r2->mr_size) < r1->mr_start)
- return (FALSE);
-
- return (TRUE);
-}
-
-static void
-memr_merge(struct mem_region *from, struct mem_region *to)
-{
- int end;
- end = imax(to->mr_start + to->mr_size, from->mr_start + from->mr_size);
- to->mr_start = imin(from->mr_start, to->mr_start);
- to->mr_size = end - to->mr_start;
-}
-
-/*
- * This is called during powerpc_init, before the system is really initialized.
- * It shall provide the total and the available regions of RAM.
- * Both lists must have a zero-size entry as terminator.
- * The available regions need not take the kernel into account, but needs
- * to provide space for two additional entry beyond the terminating one.
- */
-void
-mem_regions(struct mem_region **memp, int *memsz,
- struct mem_region **availp, int *availsz)
-{
- int phandle;
- int asz, msz, fsz;
- int i, j;
- int still_merging;
-
- /*
- * Get memory.
- */
- if ((phandle = OF_finddevice("/memory")) == -1
- || (msz = OF_getprop(phandle, "reg",
- OFmem, sizeof OFmem[0] * OFMEM_REGIONS))
- <= 0
- || (asz = OF_getprop(phandle, "available",
- OFavail, sizeof OFavail[0] * OFMEM_REGIONS))
- <= 0)
- panic("no memory?");
- *memp = OFmem;
- *memsz = msz / sizeof(struct mem_region);
-
- /*
- * OFavail may have overlapping regions - collapse these
- * and copy out remaining regions to OFfree
- */
- asz /= sizeof(struct mem_region);
- do {
- still_merging = FALSE;
- for (i = 0; i < asz; i++) {
- if (OFavail[i].mr_size == 0)
- continue;
- for (j = i+1; j < asz; j++) {
- if (OFavail[j].mr_size == 0)
- continue;
- if (memr_overlap(&OFavail[j], &OFavail[i])) {
- memr_merge(&OFavail[j], &OFavail[i]);
- /* mark inactive */
- OFavail[j].mr_size = 0;
- still_merging = TRUE;
- }
- }
- }
- } while (still_merging == TRUE);
-
- /* evict inactive ranges */
- for (i = 0, fsz = 0; i < asz; i++) {
- if (OFavail[i].mr_size != 0) {
- OFfree[fsz] = OFavail[i];
- fsz++;
- }
- }
-
- *availp = OFfree;
- *availsz = fsz;
-}
-
-void
-set_openfirm_callback(int (*openfirm)(void *))
-{
-
- ofwcall = openfirm;
-}
-
-int
-openfirmware(void *args)
-{
- long oldmsr;
- int result;
- u_int srsave[16];
- u_int i;
-
- __asm __volatile( "\t"
- "sync\n\t"
- "mfmsr %0\n\t"
- "mtmsr %1\n\t"
- "isync\n"
- : "=r" (oldmsr)
- : "r" (ofmsr[0])
- );
-
- ofw_sprg_prepare();
-
- if (pmap_bootstrapped) {
- /*
- * Swap the kernel's address space with Open Firmware's
- */
- for (i = 0; i < 16; i++) {
- srsave[i] = mfsrin(i << ADDR_SR_SHFT);
- mtsrin(i << ADDR_SR_SHFT, ofw_pmap.pm_sr[i]);
- }
-
- /*
- * Clear battable[] translations
- */
- __asm __volatile("mtdbatu 2, %0\n"
- "mtdbatu 3, %0" : : "r" (0));
- isync();
- }
-
- result = ofwcall(args);
-
- if (pmap_bootstrapped) {
- /*
- * Restore the kernel's addr space. The isync() doesn;t
- * work outside the loop unless mtsrin() is open-coded
- * in an asm statement :(
- */
- for (i = 0; i < 16; i++) {
- mtsrin(i << ADDR_SR_SHFT, srsave[i]);
- isync();
- }
- }
-
- ofw_sprg_restore();
-
- __asm( "\t"
- "mtmsr %0\n\t"
- "isync\n"
- : : "r" (oldmsr)
- );
-
- return (result);
-}
-
-void
-OF_halt()
-{
- int retval; /* dummy, this may not be needed */
-
- OF_interpret("shut-down", 1, &retval);
- for (;;); /* just in case */
-}
-
-void
-OF_reboot()
-{
- int retval; /* dummy, this may not be needed */
-
- OF_interpret("reset-all", 1, &retval);
- for (;;); /* just in case */
-}
-
-void
-OF_getetheraddr(device_t dev, u_char *addr)
-{
- phandle_t node;
-
- node = ofw_pci_find_node(dev);
- OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN);
-}
-
-/*
- * Return a bus handle and bus tag that corresponds to the register
- * numbered regno for the device referenced by the package handle
- * dev. This function is intended to be used by console drivers in
- * early boot only. It works by mapping the address of the device's
- * register in the address space of its parent and recursively walk
- * the device tree upward this way.
- */
-static void
-OF_get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep, int *pcip)
-{
- char name[16];
- uint32_t addr, size;
- int pci, res;
-
- res = OF_getprop(node, "#address-cells", &addr, sizeof(addr));
- if (res == -1)
- addr = 2;
- res = OF_getprop(node, "#size-cells", &size, sizeof(size));
- if (res == -1)
- size = 1;
- pci = 0;
- if (addr == 3 && size == 2) {
- res = OF_getprop(node, "name", name, sizeof(name));
- if (res != -1) {
- name[sizeof(name) - 1] = '\0';
- pci = (strcmp(name, "pci") == 0) ? 1 : 0;
- }
- }
- if (addrp != NULL)
- *addrp = addr;
- if (sizep != NULL)
- *sizep = size;
- if (pcip != NULL)
- *pcip = pci;
-}
-
-int
-OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
- bus_space_handle_t *handle)
-{
- uint32_t cell[32];
- bus_addr_t addr, raddr, baddr;
- bus_size_t size, rsize;
- uint32_t c, nbridge, naddr, nsize;
- phandle_t bridge, parent;
- u_int spc, rspc;
- int pci, pcib, res;
-
- /* Sanity checking. */
- if (dev == 0)
- return (EINVAL);
- bridge = OF_parent(dev);
- if (bridge == 0)
- return (EINVAL);
- if (regno < 0)
- return (EINVAL);
- if (tag == NULL || handle == NULL)
- return (EINVAL);
-
- /* Get the requested register. */
- OF_get_addr_props(bridge, &naddr, &nsize, &pci);
- res = OF_getprop(dev, (pci) ? "assigned-addresses" : "reg",
- cell, sizeof(cell));
- if (res == -1)
- return (ENXIO);
- if (res % sizeof(cell[0]))
- return (ENXIO);
- res /= sizeof(cell[0]);
- regno *= naddr + nsize;
- if (regno + naddr + nsize > res)
- return (EINVAL);
- spc = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK : ~0;
- addr = 0;
- for (c = 0; c < naddr; c++)
- addr = ((uint64_t)addr << 32) | cell[regno++];
- size = 0;
- for (c = 0; c < nsize; c++)
- size = ((uint64_t)size << 32) | cell[regno++];
-
- /*
- * Map the address range in the bridge's decoding window as given
- * by the "ranges" property. If a node doesn't have such property
- * then no mapping is done.
- */
- parent = OF_parent(bridge);
- while (parent != 0) {
- OF_get_addr_props(parent, &nbridge, NULL, &pcib);
- res = OF_getprop(bridge, "ranges", cell, sizeof(cell));
- if (res == -1)
- goto next;
- if (res % sizeof(cell[0]))
- return (ENXIO);
- res /= sizeof(cell[0]);
- regno = 0;
- while (regno < res) {
- rspc = (pci)
- ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
- : ~0;
- if (rspc != spc) {
- regno += naddr + nbridge + nsize;
- continue;
- }
- raddr = 0;
- for (c = 0; c < naddr; c++)
- raddr = ((uint64_t)raddr << 32) | cell[regno++];
- rspc = (pcib)
- ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
- : ~0;
- baddr = 0;
- for (c = 0; c < nbridge; c++)
- baddr = ((uint64_t)baddr << 32) | cell[regno++];
- rsize = 0;
- for (c = 0; c < nsize; c++)
- rsize = ((uint64_t)rsize << 32) | cell[regno++];
- if (addr < raddr || addr >= raddr + rsize)
- continue;
- addr = addr - raddr + baddr;
- if (rspc != ~0)
- spc = rspc;
- }
-
- next:
- bridge = parent;
- parent = OF_parent(bridge);
- OF_get_addr_props(bridge, &naddr, &nsize, &pci);
- }
-
- /* Default to memory mapped I/O. */
- *tag = PPC_BUS_SPACE_MEM;
- if (spc == OFW_PCI_PHYS_HI_SPACE_IO)
- *tag = PPC_BUS_SPACE_IO;
- return (bus_space_map(*tag, addr, size, 0, handle));
-}
-
-int
-mem_valid(vm_offset_t addr, int len)
-{
- int i;
-
- for (i = 0; i < OFMEM_REGIONS; i++)
- if ((addr >= OFmem[i].mr_start)
- && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size))
- return (0);
-
- return (EFAULT);
-}
diff --git a/sys/powerpc/powerpc/ofwmagic.S b/sys/powerpc/powerpc/ofwmagic.S
deleted file mode 100644
index 55af6d2..0000000
--- a/sys/powerpc/powerpc/ofwmagic.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: ofwmagic.S,v 1.2 1997/10/09 08:38:18 jtc Exp $ */
-
-/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe.
- *
- * 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 NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-
-/*
- * Magic note section used by Open Firmware.
- */
-
- .section ".note"
-
- /*# note header */
-
- /*# length of name */
- .long 8
-
- /*# note descriptor size */
- .long 20
-
- /*# note type (IEEE 1275) */
- .long 0x1275
-
- /*# name of owner */
- .asciz "PowerPC"
- .balign 4
-
-
- /*# note descriptor */
-
- /*# real mode (-1) or virtual mode (0) */
- .long 0
-
- /*# real-base */
- .long -1
- /*# real-size */
- .long -1
-
- /*# virt-base */
- .long -1
- /*# virt-size */
- .long -1
diff --git a/sys/powerpc/powerpc/swtch.S b/sys/powerpc/powerpc/swtch.S
deleted file mode 100644
index 1a09d87..0000000
--- a/sys/powerpc/powerpc/swtch.S
+++ /dev/null
@@ -1,158 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
-
-/*-
- * Copyright (C) 2001 Benno Rice
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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.
-*/
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "assym.s"
-
-#include <sys/syscall.h>
-
-#include <machine/trap.h>
-#include <machine/param.h>
-#include <machine/sr.h>
-#include <machine/psl.h>
-#include <machine/asm.h>
-
-/*
- * void cpu_switch(struct thread *old,
- * struct thread *new,
- * struct mutex *mtx);
- *
- * Switch to a new thread saving the current state in the old thread.
- */
-ENTRY(cpu_switch)
- stw %r5,TD_LOCK(%r3) /* ULE: update old thread's lock */
- /* XXX needs to change for MP */
-
- lwz %r5,TD_PCB(%r3) /* Get the old thread's PCB ptr */
- mr %r12,%r2
- stmw %r12,PCB_CONTEXT(%r5) /* Save the non-volatile GP regs.
- These can now be used for scratch */
-
- mfcr %r16 /* Save the condition register */
- stw %r16,PCB_CR(%r5)
- mflr %r16 /* Save the link register */
- stw %r16,PCB_LR(%r5)
- mfsr %r16,USER_SR /* Save USER_SR for copyin/out */
- isync
- stw %r16,PCB_USR(%r5)
- stw %r1,PCB_SP(%r5) /* Save the stack pointer */
-
- mr %r14,%r3 /* Copy the old thread ptr... */
- mr %r15,%r4 /* and the new thread ptr in scratch */
-
- lwz %r6,PCB_FLAGS(%r5) /* Save FPU context if needed */
- andi. %r6, %r6, PCB_FPU
- beq .L1
- bl save_fpu
- mr %r3,%r14 /* restore old thread ptr */
-.L1:
- bl pmap_deactivate /* Deactivate the current pmap */
-
- mr %r3,%r15 /* Get new thread ptr */
- bl pmap_activate /* Activate the new address space */
-
- mfsprg %r7,0 /* Get the pcpu pointer */
- stw %r15,PC_CURTHREAD(%r7) /* Store new current thread */
- lwz %r17,TD_PCB(%r15) /* Store new current PCB */
- stw %r17,PC_CURPCB(%r7)
-
- lwz %r6, PCB_FLAGS(%r17) /* Restore FPU context if needed */
- andi. %r6, %r6, PCB_FPU
- beq .L2
- mr %r3,%r15 /* Pass curthread to enable_fpu */
- bl enable_fpu
-
- /* thread to restore is in r3 */
-.L2:
- mr %r3,%r17 /* Recover PCB ptr */
- lmw %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs */
- mr %r2,%r12
- lwz %r5,PCB_CR(%r3) /* Load the condition register */
- mtcr %r5
- lwz %r5,PCB_LR(%r3) /* Load the link register */
- mtlr %r5
- lwz %r5,PCB_USR(%r3) /* Load the USER_SR segment reg */
- mtsr USER_SR,%r5
- isync
- lwz %r1,PCB_SP(%r3) /* Load the stack pointer */
- blr
-
-/*
- * savectx(pcb)
- * Update pcb, saving current processor state
- */
-ENTRY(savectx)
- mr %r12,%r2
- stmw %r12,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
- mfcr %r4 /* Save the condition register */
- stw %r4,PCB_CONTEXT(%r3)
- blr
-
-/*
- * fork_trampoline()
- * Set up the return from cpu_fork()
- */
-ENTRY(fork_trampoline)
- lwz %r3,CF_FUNC(%r1)
- lwz %r4,CF_ARG0(%r1)
- lwz %r5,CF_ARG1(%r1)
- bl fork_exit
- addi %r1,%r1,CF_SIZE-FSP /* Allow 8 bytes in front of
- trapframe to simulate FRAME_SETUP
- does when allocating space for
- a frame pointer/saved LR */
- b trapexit
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
deleted file mode 100644
index b691a65..0000000
--- a/sys/powerpc/powerpc/trap.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- *
- * $NetBSD: trap.c,v 1.58 2002/03/04 04:07:35 dbj Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_ktrace.h"
-
-#include <sys/param.h>
-#include <sys/kdb.h>
-#include <sys/proc.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/pioctl.h>
-#include <sys/ptrace.h>
-#include <sys/reboot.h>
-#include <sys/syscall.h>
-#include <sys/sysent.h>
-#include <sys/systm.h>
-#include <sys/uio.h>
-#include <sys/signalvar.h>
-#ifdef KTRACE
-#include <sys/ktrace.h>
-#endif
-#include <sys/vmmeter.h>
-
-#include <security/audit/audit.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_map.h>
-#include <vm/vm_page.h>
-
-#include <machine/cpu.h>
-#include <machine/db_machdep.h>
-#include <machine/fpu.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-#include <machine/pmap.h>
-#include <machine/psl.h>
-#include <machine/trap.h>
-#include <machine/spr.h>
-#include <machine/sr.h>
-
-static void trap_fatal(struct trapframe *frame);
-static void printtrap(u_int vector, struct trapframe *frame, int isfatal,
- int user);
-static int trap_pfault(struct trapframe *frame, int user);
-static int fix_unaligned(struct thread *td, struct trapframe *frame);
-static int handle_onfault(struct trapframe *frame);
-static void syscall(struct trapframe *frame);
-
-static __inline void setusr(u_int);
-
-int setfault(faultbuf); /* defined in locore.S */
-
-/* Why are these not defined in a header? */
-int badaddr(void *, size_t);
-int badaddr_read(void *, size_t, int *);
-
-extern char *syscallnames[];
-
-struct powerpc_exception {
- u_int vector;
- char *name;
-};
-
-static struct powerpc_exception powerpc_exceptions[] = {
- { 0x0100, "system reset" },
- { 0x0200, "machine check" },
- { 0x0300, "data storage interrupt" },
- { 0x0400, "instruction storage interrupt" },
- { 0x0500, "external interrupt" },
- { 0x0600, "alignment" },
- { 0x0700, "program" },
- { 0x0800, "floating-point unavailable" },
- { 0x0900, "decrementer" },
- { 0x0c00, "system call" },
- { 0x0d00, "trace" },
- { 0x0e00, "floating-point assist" },
- { 0x0f00, "performance monitoring" },
- { 0x0f20, "altivec unavailable" },
- { 0x1000, "instruction tlb miss" },
- { 0x1100, "data load tlb miss" },
- { 0x1200, "data store tlb miss" },
- { 0x1300, "instruction breakpoint" },
- { 0x1400, "system management" },
- { 0x1600, "altivec assist" },
- { 0x1700, "thermal management" },
- { 0x2000, "run mode/trace" },
- { 0x3000, NULL }
-};
-
-static const char *
-trapname(u_int vector)
-{
- struct powerpc_exception *pe;
-
- for (pe = powerpc_exceptions; pe->vector != 0x3000; pe++) {
- if (pe->vector == vector)
- return (pe->name);
- }
-
- return ("unknown");
-}
-
-void
-trap(struct trapframe *frame)
-{
- struct thread *td;
- struct proc *p;
- int sig, type, user;
- u_int ucode;
- ksiginfo_t ksi;
-
- PCPU_INC(cnt.v_trap);
-
- td = PCPU_GET(curthread);
- p = td->td_proc;
-
- type = ucode = frame->exc;
- sig = 0;
- user = frame->srr1 & PSL_PR;
-
- CTR3(KTR_TRAP, "trap: %s type=%s (%s)", td->td_name,
- trapname(type), user ? "user" : "kernel");
-
- if (user) {
- td->td_pticks = 0;
- td->td_frame = frame;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
-
- /* User Mode Traps */
- switch (type) {
- case EXC_RUNMODETRC:
- case EXC_TRC:
- frame->srr1 &= ~PSL_SE;
- sig = SIGTRAP;
- break;
-
- case EXC_DSI:
- case EXC_ISI:
- sig = trap_pfault(frame, 1);
- break;
-
- case EXC_SC:
- syscall(frame);
- break;
-
- case EXC_FPU:
- KASSERT((td->td_pcb->pcb_flags & PCB_FPU) != PCB_FPU,
- ("FPU already enabled for thread"));
- enable_fpu(td);
- break;
-
-#ifdef ALTIVEC
- case EXC_VEC:
- if ((vecthread = PCPU_GET(vecthread)) != NULL) {
- KASSERT(vecthread != td,
- ("altivec already enabled"));
- save_vec(vecthread);
- }
- PCPU_SET(vecthread, td);
- td->td_pcb->pcb_veccpu = PCPU_GET(cpuid);
- enable_vec(td);
- frame->srr1 |= PSL_VEC;
- break;
-#else
- case EXC_VEC:
- case EXC_VECAST:
- sig = SIGILL;
- break;
-#endif /* ALTIVEC */
-
- case EXC_ALI:
- if (fix_unaligned(td, frame) != 0)
- sig = SIGBUS;
- else
- frame->srr0 += 4;
- break;
-
- case EXC_PGM:
- /* XXX temporarily */
- /* XXX: Magic Number? */
- if (frame->srr1 & 0x0002000)
- sig = SIGTRAP;
- else
- sig = SIGILL;
- break;
-
- default:
- trap_fatal(frame);
- }
- } else {
- /* Kernel Mode Traps */
-
- KASSERT(cold || td->td_ucred != NULL,
- ("kernel trap doesn't have ucred"));
- switch (type) {
- case EXC_DSI:
- if (trap_pfault(frame, 0) == 0)
- return;
- break;
- case EXC_MCHK:
- if (handle_onfault(frame))
- return;
- break;
- default:
- break;
- }
- trap_fatal(frame);
- }
-
-#ifdef ALTIVEC
- if (td != PCPU_GET(vecthread) ||
- td->td_pcb->pcb_veccpu != PCPU_GET(cpuid))
- frame->srr1 &= ~PSL_VEC;
-#endif /* ALTIVEC */
-
- if (sig != 0) {
- if (p->p_sysent->sv_transtrap != NULL)
- sig = (p->p_sysent->sv_transtrap)(sig, type);
- ksiginfo_init_trap(&ksi);
- ksi.ksi_signo = sig;
- ksi.ksi_code = (int) ucode; /* XXX, not POSIX */
- /* ksi.ksi_addr = ? */
- ksi.ksi_trapno = type;
- trapsignal(td, &ksi);
- }
-
- userret(td, frame);
- mtx_assert(&Giant, MA_NOTOWNED);
-}
-
-static void
-trap_fatal(struct trapframe *frame)
-{
-
- printtrap(frame->exc, frame, 1, (frame->srr1 & PSL_PR));
-#ifdef KDB
- if ((debugger_on_panic || kdb_active) &&
- kdb_trap(frame->exc, 0, frame))
- return;
-#endif
- panic("%s trap", trapname(frame->exc));
-}
-
-static void
-printtrap(u_int vector, struct trapframe *frame, int isfatal, int user)
-{
-
- printf("\n");
- printf("%s %s trap:\n", isfatal ? "fatal" : "handled",
- user ? "user" : "kernel");
- printf("\n");
- printf(" exception = 0x%x (%s)\n", vector >> 8,
- trapname(vector));
- switch (vector) {
- case EXC_DSI:
- printf(" virtual address = 0x%x\n", frame->dar);
- break;
- case EXC_ISI:
- printf(" virtual address = 0x%x\n", frame->srr0);
- break;
- }
- printf(" srr0 = 0x%x\n", frame->srr0);
- printf(" srr1 = 0x%x\n", frame->srr1);
- printf(" curthread = %p\n", curthread);
- if (curthread != NULL)
- printf(" pid = %d, comm = %s\n",
- curthread->td_proc->p_pid, curthread->td_name);
- printf("\n");
-}
-
-/*
- * Handles a fatal fault when we have onfault state to recover. Returns
- * non-zero if there was onfault recovery state available.
- */
-static int
-handle_onfault(struct trapframe *frame)
-{
- struct thread *td;
- faultbuf *fb;
-
- td = curthread;
- fb = td->td_pcb->pcb_onfault;
- if (fb != NULL) {
- frame->srr0 = (*fb)[0];
- frame->fixreg[1] = (*fb)[1];
- frame->fixreg[2] = (*fb)[2];
- frame->fixreg[3] = 1;
- frame->cr = (*fb)[3];
- bcopy(&(*fb)[4], &frame->fixreg[13],
- 19 * sizeof(register_t));
- return (1);
- }
- return (0);
-}
-
-void
-syscall(struct trapframe *frame)
-{
- caddr_t params;
- struct sysent *callp;
- struct thread *td;
- struct proc *p;
- int error, n;
- size_t narg;
- register_t args[10];
- u_int code;
-
- td = PCPU_GET(curthread);
- p = td->td_proc;
-
- PCPU_INC(cnt.v_syscall);
-
-#ifdef KSE
- if (p->p_flag & P_SA)
- thread_user_enter(td);
-#endif
-
- code = frame->fixreg[0];
- params = (caddr_t)(frame->fixreg + FIRSTARG);
- n = NARGREG;
-
- if (p->p_sysent->sv_prepsyscall) {
- /*
- * The prep code is MP aware.
- */
- (*p->p_sysent->sv_prepsyscall)(frame, args, &code, &params);
- } else if (code == SYS_syscall) {
- /*
- * code is first argument,
- * followed by actual args.
- */
- code = *(u_int *) params;
- params += sizeof(register_t);
- n -= 1;
- } else if (code == SYS___syscall) {
- /*
- * Like syscall, but code is a quad,
- * so as to maintain quad alignment
- * for the rest of the args.
- */
- params += sizeof(register_t);
- code = *(u_int *) params;
- params += sizeof(register_t);
- n -= 2;
- }
-
- if (p->p_sysent->sv_mask)
- code &= p->p_sysent->sv_mask;
-
- if (code >= p->p_sysent->sv_size)
- callp = &p->p_sysent->sv_table[0];
- else
- callp = &p->p_sysent->sv_table[code];
-
- narg = callp->sy_narg;
-
- if (narg > n) {
- bcopy(params, args, n * sizeof(register_t));
- error = copyin(MOREARGS(frame->fixreg[1]), args + n,
- (narg - n) * sizeof(register_t));
- params = (caddr_t)args;
- } else
- error = 0;
-
- CTR5(KTR_SYSC, "syscall: p=%s %s(%x %x %x)", td->td_name,
- syscallnames[code],
- frame->fixreg[FIRSTARG],
- frame->fixreg[FIRSTARG+1],
- frame->fixreg[FIRSTARG+2]);
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSCALL))
- ktrsyscall(code, narg, (register_t *)params);
-#endif
-
- td->td_syscalls++;
-
- if (error == 0) {
- td->td_retval[0] = 0;
- td->td_retval[1] = frame->fixreg[FIRSTARG + 1];
-
- STOPEVENT(p, S_SCE, narg);
-
- PTRACESTOP_SC(p, td, S_PT_SCE);
-
- AUDIT_SYSCALL_ENTER(code, td);
- error = (*callp->sy_call)(td, params);
- AUDIT_SYSCALL_EXIT(error, td);
-
- CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", td->td_name,
- syscallnames[code], td->td_retval[0]);
- }
- switch (error) {
- case 0:
- if (frame->fixreg[0] == SYS___syscall &&
- code != SYS_freebsd6_lseek && code != SYS_lseek) {
- /*
- * 64-bit return, 32-bit syscall. Fixup byte order
- */
- frame->fixreg[FIRSTARG] = 0;
- frame->fixreg[FIRSTARG + 1] = td->td_retval[0];
- } else {
- frame->fixreg[FIRSTARG] = td->td_retval[0];
- frame->fixreg[FIRSTARG + 1] = td->td_retval[1];
- }
- /* XXX: Magic number */
- frame->cr &= ~0x10000000;
- break;
- case ERESTART:
- /*
- * Set user's pc back to redo the system call.
- */
- frame->srr0 -= 4;
- break;
- case EJUSTRETURN:
- /* nothing to do */
- break;
- default:
- if (p->p_sysent->sv_errsize) {
- if (error >= p->p_sysent->sv_errsize)
- error = -1; /* XXX */
- else
- error = p->p_sysent->sv_errtbl[error];
- }
- frame->fixreg[FIRSTARG] = error;
- /* XXX: Magic number: Carry Flag Equivalent? */
- frame->cr |= 0x10000000;
- break;
- }
-
- /*
- * Check for misbehavior.
- */
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- KASSERT(td->td_critnest == 0,
- ("System call %s returning in a critical section",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
- KASSERT(td->td_locks == 0,
- ("System call %s returning with %d locks held",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
- td->td_locks));
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSRET))
- ktrsysret(code, error, td->td_retval[0]);
-#endif
-
- /*
- * Does the comment in the i386 code about errno apply here?
- */
- STOPEVENT(p, S_SCX, code);
-
- PTRACESTOP_SC(p, td, S_PT_SCX);
-}
-
-static int
-trap_pfault(struct trapframe *frame, int user)
-{
- vm_offset_t eva, va;
- struct thread *td;
- struct proc *p;
- vm_map_t map;
- vm_prot_t ftype;
- int rv;
- u_int user_sr;
-
- td = curthread;
- p = td->td_proc;
- if (frame->exc == EXC_ISI) {
- eva = frame->srr0;
- ftype = VM_PROT_READ | VM_PROT_EXECUTE;
- } else {
- eva = frame->dar;
- if (frame->dsisr & DSISR_STORE)
- ftype = VM_PROT_WRITE;
- else
- ftype = VM_PROT_READ;
- }
-
- if (user) {
- map = &p->p_vmspace->vm_map;
- } else {
- if ((eva >> ADDR_SR_SHFT) == USER_SR) {
- if (p->p_vmspace == NULL)
- return (SIGSEGV);
-
- __asm ("mfsr %0, %1"
- : "=r"(user_sr)
- : "K"(USER_SR));
- eva &= ADDR_PIDX | ADDR_POFF;
- eva |= user_sr << ADDR_SR_SHFT;
- map = &p->p_vmspace->vm_map;
- } else {
- map = kernel_map;
- }
- }
- va = trunc_page(eva);
-
- if (map != kernel_map) {
- /*
- * Keep swapout from messing with us during this
- * critical time.
- */
- PROC_LOCK(p);
- ++p->p_lock;
- PROC_UNLOCK(p);
-
- /* Fault in the user page: */
- rv = vm_fault(map, va, ftype,
- (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
- : VM_FAULT_NORMAL);
-
- PROC_LOCK(p);
- --p->p_lock;
- PROC_UNLOCK(p);
- } else {
- /*
- * Don't have to worry about process locking or stacks in the
- * kernel.
- */
- rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
- }
-
- if (rv == KERN_SUCCESS)
- return (0);
-
- if (!user && handle_onfault(frame))
- return (0);
-
- return (SIGSEGV);
-}
-
-static __inline void
-setusr(u_int content)
-{
- __asm __volatile ("isync; mtsr %0,%1; isync"
- :: "n"(USER_SR), "r"(content));
-}
-
-int
-badaddr(void *addr, size_t size)
-{
- return (badaddr_read(addr, size, NULL));
-}
-
-int
-badaddr_read(void *addr, size_t size, int *rptr)
-{
- struct thread *td;
- faultbuf env;
- int x;
-
- /* Get rid of any stale machine checks that have been waiting. */
- __asm __volatile ("sync; isync");
-
- td = PCPU_GET(curthread);
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = 0;
- __asm __volatile ("sync");
- return 1;
- }
-
- __asm __volatile ("sync");
-
- switch (size) {
- case 1:
- x = *(volatile int8_t *)addr;
- break;
- case 2:
- x = *(volatile int16_t *)addr;
- break;
- case 4:
- x = *(volatile int32_t *)addr;
- break;
- default:
- panic("badaddr: invalid size (%d)", size);
- }
-
- /* Make sure we took the machine check, if we caused one. */
- __asm __volatile ("sync; isync");
-
- td->td_pcb->pcb_onfault = 0;
- __asm __volatile ("sync"); /* To be sure. */
-
- /* Use the value to avoid reorder. */
- if (rptr)
- *rptr = x;
-
- return (0);
-}
-
-/*
- * For now, this only deals with the particular unaligned access case
- * that gcc tends to generate. Eventually it should handle all of the
- * possibilities that can happen on a 32-bit PowerPC in big-endian mode.
- */
-
-static int
-fix_unaligned(struct thread *td, struct trapframe *frame)
-{
- struct thread *fputhread;
- int indicator, reg;
- double *fpr;
-
- indicator = EXC_ALI_OPCODE_INDICATOR(frame->dsisr);
-
- switch (indicator) {
- case EXC_ALI_LFD:
- case EXC_ALI_STFD:
- reg = EXC_ALI_RST(frame->dsisr);
- fpr = &td->td_pcb->pcb_fpu.fpr[reg];
- fputhread = PCPU_GET(fputhread);
-
- /* Juggle the FPU to ensure that we've initialized
- * the FPRs, and that their current state is in
- * the PCB.
- */
- if (fputhread != td) {
- if (fputhread)
- save_fpu(fputhread);
- enable_fpu(td);
- }
- save_fpu(td);
-
- if (indicator == EXC_ALI_LFD) {
- if (copyin((void *)frame->dar, fpr,
- sizeof(double)) != 0)
- return -1;
- enable_fpu(td);
- } else {
- if (copyout(fpr, (void *)frame->dar,
- sizeof(double)) != 0)
- return -1;
- }
- return 0;
- break;
- }
-
- return -1;
-}
diff --git a/sys/powerpc/powerpc/trap_subr.S b/sys/powerpc/powerpc/trap_subr.S
deleted file mode 100644
index 06ed891..0000000
--- a/sys/powerpc/powerpc/trap_subr.S
+++ /dev/null
@@ -1,540 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */
-
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * 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 TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
- */
-
-/*
- * NOTICE: This is not a standalone file. to use it, #include it in
- * your port's locore.S, like so:
- *
- * #include <powerpc/powerpc/trap_subr.S>
- */
-
-/*
- * Save/restore segment registers
- */
-#define RESTORE_SRS(pmap,sr) mtsr 0,sr; \
- lwz sr,1*4(pmap); mtsr 1,sr; \
- lwz sr,2*4(pmap); mtsr 2,sr; \
- lwz sr,3*4(pmap); mtsr 3,sr; \
- lwz sr,4*4(pmap); mtsr 4,sr; \
- lwz sr,5*4(pmap); mtsr 5,sr; \
- lwz sr,6*4(pmap); mtsr 6,sr; \
- lwz sr,7*4(pmap); mtsr 7,sr; \
- lwz sr,8*4(pmap); mtsr 8,sr; \
- lwz sr,9*4(pmap); mtsr 9,sr; \
- lwz sr,10*4(pmap); mtsr 10,sr; \
- lwz sr,11*4(pmap); mtsr 11,sr; \
- lwz sr,12*4(pmap); mtsr 12,sr; \
- lwz sr,13*4(pmap); mtsr 13,sr; \
- lwz sr,14*4(pmap); mtsr 14,sr; \
- lwz sr,15*4(pmap); mtsr 15,sr; isync;
-
-/*
- * User SRs are loaded through a pointer to the current pmap.
- */
-#define RESTORE_USER_SRS(pmap,sr) \
- GET_CPUINFO(pmap); \
- lwz pmap,PC_CURPMAP(pmap); \
- lwzu sr,PM_SR(pmap); \
- RESTORE_SRS(pmap,sr)
-
-/*
- * Kernel SRs are loaded directly from kernel_pmap_
- */
-#define RESTORE_KERN_SRS(pmap,sr) \
- lis pmap,CNAME(kernel_pmap_store)@ha; \
- lwzu sr,CNAME(kernel_pmap_store)+PM_SR@l(pmap); \
- RESTORE_SRS(pmap,sr)
-
-/*
- * FRAME_SETUP assumes:
- * SPRG1 SP (1)
- * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps)
- * r28 LR
- * r29 CR
- * r30 scratch
- * r31 scratch
- * r1 kernel stack
- * LR trap type (from calling address, mask with 0xff00)
- * SRR0/1 as at start of trap
- */
-#define FRAME_SETUP(savearea) \
-/* Have to enable translation to allow access of kernel stack: */ \
- GET_CPUINFO(%r31); \
- mfsrr0 %r30; \
- stw %r30,(savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \
- mfsrr1 %r30; \
- stw %r30,(savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \
- mfmsr %r30; \
- ori %r30,%r30,(PSL_DR|PSL_IR|PSL_RI)@l; /* relocation on */ \
- mtmsr %r30; /* stack can now be accessed */ \
- isync; \
- mfsprg1 %r31; /* get saved SP */ \
- stwu %r31,-FRAMELEN(%r1); /* save it in the callframe */ \
- stw %r0, FRAME_0+8(%r1); /* save r0 in the trapframe */ \
- stw %r31,FRAME_1+8(%r1); /* save SP " " */ \
- stw %r2, FRAME_2+8(%r1); /* save r2 " " */ \
- stw %r28,FRAME_LR+8(%r1); /* save LR " " */ \
- stw %r29,FRAME_CR+8(%r1); /* save CR " " */ \
- GET_CPUINFO(%r2); \
- lwz %r28,(savearea+CPUSAVE_R28)(%r2); /* get saved r28 */ \
- lwz %r29,(savearea+CPUSAVE_R29)(%r2); /* get saved r29 */ \
- lwz %r30,(savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \
- lwz %r31,(savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \
- stw %r3, FRAME_3+8(%r1); /* save r3-r31 */ \
- stw %r4, FRAME_4+8(%r1); \
- stw %r5, FRAME_5+8(%r1); \
- stw %r6, FRAME_6+8(%r1); \
- stw %r7, FRAME_7+8(%r1); \
- stw %r8, FRAME_8+8(%r1); \
- stw %r9, FRAME_9+8(%r1); \
- stw %r10, FRAME_10+8(%r1); \
- stw %r11, FRAME_11+8(%r1); \
- stw %r12, FRAME_12+8(%r1); \
- stw %r13, FRAME_13+8(%r1); \
- stw %r14, FRAME_14+8(%r1); \
- stw %r15, FRAME_15+8(%r1); \
- stw %r16, FRAME_16+8(%r1); \
- stw %r17, FRAME_17+8(%r1); \
- stw %r18, FRAME_18+8(%r1); \
- stw %r19, FRAME_19+8(%r1); \
- stw %r20, FRAME_20+8(%r1); \
- stw %r21, FRAME_21+8(%r1); \
- stw %r22, FRAME_22+8(%r1); \
- stw %r23, FRAME_23+8(%r1); \
- stw %r24, FRAME_24+8(%r1); \
- stw %r25, FRAME_25+8(%r1); \
- stw %r26, FRAME_26+8(%r1); \
- stw %r27, FRAME_27+8(%r1); \
- stw %r28, FRAME_28+8(%r1); \
- stw %r29, FRAME_29+8(%r1); \
- stw %r30, FRAME_30+8(%r1); \
- stw %r31, FRAME_31+8(%r1); \
- lwz %r28,(savearea+CPUSAVE_DAR)(%r2); /* saved DAR */ \
- lwz %r29,(savearea+CPUSAVE_DSISR)(%r2);/* saved DSISR */ \
- lwz %r30,(savearea+CPUSAVE_SRR0)(%r2); /* saved SRR0 */ \
- lwz %r31,(savearea+CPUSAVE_SRR1)(%r2); /* saved SRR1 */ \
- mfxer %r3; \
- mfctr %r4; \
- mflr %r5; \
- andi. %r5,%r5,0xff00; /* convert LR to exc # */ \
- stw %r3, FRAME_XER+8(1); /* save xer/ctr/exc */ \
- stw %r4, FRAME_CTR+8(1); \
- stw %r5, FRAME_EXC+8(1); \
- stw %r28,FRAME_DAR+8(1); \
- stw %r29,FRAME_DSISR+8(1); /* save dsisr/srr0/srr1 */ \
- stw %r30,FRAME_SRR0+8(1); \
- stw %r31,FRAME_SRR1+8(1)
-
-#define FRAME_LEAVE(savearea) \
-/* Now restore regs: */ \
- lwz %r2,FRAME_SRR0+8(%r1); \
- lwz %r3,FRAME_SRR1+8(%r1); \
- lwz %r4,FRAME_CTR+8(%r1); \
- lwz %r5,FRAME_XER+8(%r1); \
- lwz %r6,FRAME_LR+8(%r1); \
- GET_CPUINFO(%r7); \
- stw %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \
- stw %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \
- lwz %r7,FRAME_CR+8(%r1); \
- mtctr %r4; \
- mtxer %r5; \
- mtlr %r6; \
- mtsprg1 %r7; /* save cr */ \
- lwz %r31,FRAME_31+8(%r1); /* restore r0-31 */ \
- lwz %r30,FRAME_30+8(%r1); \
- lwz %r29,FRAME_29+8(%r1); \
- lwz %r28,FRAME_28+8(%r1); \
- lwz %r27,FRAME_27+8(%r1); \
- lwz %r26,FRAME_26+8(%r1); \
- lwz %r25,FRAME_25+8(%r1); \
- lwz %r24,FRAME_24+8(%r1); \
- lwz %r23,FRAME_23+8(%r1); \
- lwz %r22,FRAME_22+8(%r1); \
- lwz %r21,FRAME_21+8(%r1); \
- lwz %r20,FRAME_20+8(%r1); \
- lwz %r19,FRAME_19+8(%r1); \
- lwz %r18,FRAME_18+8(%r1); \
- lwz %r17,FRAME_17+8(%r1); \
- lwz %r16,FRAME_16+8(%r1); \
- lwz %r15,FRAME_15+8(%r1); \
- lwz %r14,FRAME_14+8(%r1); \
- lwz %r13,FRAME_13+8(%r1); \
- lwz %r12,FRAME_12+8(%r1); \
- lwz %r11,FRAME_11+8(%r1); \
- lwz %r10,FRAME_10+8(%r1); \
- lwz %r9, FRAME_9+8(%r1); \
- lwz %r8, FRAME_8+8(%r1); \
- lwz %r7, FRAME_7+8(%r1); \
- lwz %r6, FRAME_6+8(%r1); \
- lwz %r5, FRAME_5+8(%r1); \
- lwz %r4, FRAME_4+8(%r1); \
- lwz %r3, FRAME_3+8(%r1); \
- lwz %r2, FRAME_2+8(%r1); \
- lwz %r0, FRAME_0+8(%r1); \
- lwz %r1, FRAME_1+8(%r1); \
-/* Can't touch %r1 from here on */ \
- mtsprg2 %r2; /* save r2 & r3 */ \
- mtsprg3 %r3; \
-/* Disable translation, machine check and recoverability: */ \
- mfmsr %r2; \
- andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \
- mtmsr %r2; \
- isync; \
-/* Decide whether we return to user mode: */ \
- GET_CPUINFO(%r2); \
- lwz %r3,(savearea+CPUSAVE_SRR1)(%r2); \
- mtcr %r3; \
- bf 17,1f; /* branch if PSL_PR is false */ \
-/* Restore user SRs */ \
- RESTORE_USER_SRS(%r2,%r3); \
-1: mfsprg1 %r2; /* restore cr */ \
- mtcr %r2; \
- GET_CPUINFO(%r2); \
- lwz %r3,(savearea+CPUSAVE_SRR0)(%r2); /* restore srr0 */ \
- mtsrr0 %r3; \
- lwz %r3,(savearea+CPUSAVE_SRR1)(%r2); /* restore srr1 */ \
- mtsrr1 %r3; \
- mfsprg2 %r2; /* restore r2 & r3 */ \
- mfsprg3 %r3
-
-#ifdef KDB
-/*
- * Define the kdb debugger stack
- */
- .data
-GLOBAL(dbstk)
- .space INTSTK+8 /* kdb stack */
-#endif
-
-/*
- * This code gets copied to all the trap vectors
- * (except ISI/DSI, ALI, and the interrupts)
- */
- .text
- .globl CNAME(trapcode),CNAME(trapsize)
-CNAME(trapcode):
- mtsprg1 %r1 /* save SP */
- GET_CPUINFO(%r1)
- stw %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) /* free r28-r31 */
- stw %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1)
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1)
- mfsprg1 %r1 /* restore SP, in case of branch */
- mflr %r28 /* save LR */
- mfcr %r29 /* save CR */
-/* Test whether we already had PR set */
- mfsrr1 %r31
- mtcr %r31
- bla s_trap /* LR & 0xff00 is exception # */
-CNAME(trapsize) = .-CNAME(trapcode)
-
-/*
- * For ALI: has to save DSISR and DAR
- */
- .globl CNAME(alitrap),CNAME(alisize)
-CNAME(alitrap):
- mtsprg1 %r1 /* save SP */
- GET_CPUINFO(%r1)
- stw %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) /* free r28-r31 */
- stw %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1)
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1)
- mfdar %r30
- mfdsisr %r31
- stw %r30,(PC_TEMPSAVE+CPUSAVE_DAR)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_DSISR)(%r1)
- mfsprg1 %r1 /* restore SP, in case of branch */
- mflr %r28 /* save LR */
- mfcr %r29 /* save CR */
-/* Test whether we already had PR set */
- mfsrr1 %r31
- mtcr %r31
- bla s_trap /* LR & 0xff00 is exception # */
-CNAME(alisize) = .-CNAME(alitrap)
-
-/*
- * Similar to the above for DSI
- * Has to handle BAT spills
- * and standard pagetable spills
- */
- .globl CNAME(dsitrap),CNAME(dsisize)
-CNAME(dsitrap):
- mtsprg1 %r1 /* save SP */
- GET_CPUINFO(%r1)
- stw %r28,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* free r28-r31 */
- stw %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1)
- stw %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1)
- stw %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1)
- mfsprg1 %r1 /* restore SP */
- mfcr %r29 /* save CR */
- mfxer %r30 /* save XER */
- mtsprg2 %r30 /* in SPRG2 */
- mfsrr1 %r31 /* test kernel mode */
- mtcr %r31
- bt 17,1f /* branch if PSL_PR is set */
- mfdar %r31 /* get fault address */
- rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
-
- /* get batu */
- addis %r31,%r31,CNAME(battable)@ha
- lwz %r30,CNAME(battable)@l(31)
- mtcr %r30
- bf 30,1f /* branch if supervisor valid is
- false */
- /* get batl */
- lwz %r31,CNAME(battable)+4@l(31)
-/* We randomly use the highest two bat registers here */
- mftb %r28
- andi. %r28,%r28,1
- bne 2f
- mtdbatu 2,%r30
- mtdbatl 2,%r31
- b 3f
-2:
- mtdbatu 3,%r30
- mtdbatl 3,%r31
-3:
- mfsprg2 %r30 /* restore XER */
- mtxer %r30
- mtcr %r29 /* restore CR */
- mtsprg1 %r1
- GET_CPUINFO(%r1)
- lwz %r28,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* restore r28-r31 */
- lwz %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1)
- lwz %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1)
- lwz %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1)
- mfsprg1 %r1
- rfi /* return to trapped code */
-1:
- mflr %r28 /* save LR (SP already saved) */
- bla disitrap
-CNAME(dsisize) = .-CNAME(dsitrap)
-
-/*
- * Preamble code for DSI/ISI traps
- */
-disitrap:
- GET_CPUINFO(%r1)
- lwz %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1)
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R28)(%r1)
- lwz %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R29)(%r1)
- lwz %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1)
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1)
- lwz %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1)
- mfdar %r30
- mfdsisr %r31
- stw %r30,(PC_TEMPSAVE+CPUSAVE_DAR)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_DSISR)(%r1)
-
-#ifdef KDB
- /* Try and detect a kernel stack overflow */
- mfsrr1 %r31
- mtcr %r31
- bt 17,realtrap /* branch is user mode */
- mfsprg1 %r31 /* get old SP */
- sub. %r30,%r31,%r30 /* SP - DAR */
- bge 1f
- neg %r30,%r30 /* modulo value */
-1: cmplwi %cr0,%r30,4096 /* is DAR within a page of SP? */
- bge %cr0,realtrap /* no, too far away. */
-
- /* Now convert this DSI into a DDB trap. */
- GET_CPUINFO(%r1)
- lwz %r30,(PC_TEMPSAVE+CPUSAVE_DAR)(%r1) /* get DAR */
- stw %r30,(PC_DBSAVE +CPUSAVE_DAR)(%r1) /* save DAR */
- lwz %r30,(PC_TEMPSAVE+CPUSAVE_DSISR)(%r1) /* get DSISR */
- lwz %r30,(PC_DBSAVE +CPUSAVE_DSISR)(%r1) /* save DSISR */
- lwz %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */
- stw %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */
- lwz %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */
- stw %r31,(PC_DBSAVE +CPUSAVE_R29)(%r1) /* save r29 */
- lwz %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) /* get r30 */
- stw %r30,(PC_DBSAVE +CPUSAVE_R30)(%r1) /* save r30 */
- lwz %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) /* get r31 */
- stw %r31,(PC_DBSAVE +CPUSAVE_R31)(%r1) /* save r31 */
- lis %r1,dbstk+INTSTK@ha /* get new SP */
- addi %r1,%r1,dbstk+INTSTK@l
- b dbtrap
-#endif
-
- /* XXX need stack probe here */
-realtrap:
-/* Test whether we already had PR set */
- mfsrr1 %r1
- mtcr %r1
- mfsprg1 %r1 /* restore SP (might have been
- overwritten) */
-s_trap:
- bf 17,k_trap /* branch if PSL_PR is false */
- GET_CPUINFO(%r1)
-u_trap:
- lwz %r1,PC_CURPCB(%r1)
- RESTORE_KERN_SRS(%r30,%r31) /* enable kernel mapping */
-
-/*
- * Now the common trap catching code.
- */
-k_trap:
- FRAME_SETUP(PC_TEMPSAVE)
-/* Call C interrupt dispatcher: */
-trapagain:
- addi %r3,%r1,8
- bl CNAME(powerpc_interrupt)
- .globl CNAME(trapexit) /* backtrace code sentinel */
-CNAME(trapexit):
-
-/* Disable interrupts: */
- mfmsr %r3
- andi. %r3,%r3,~PSL_EE@l
- mtmsr %r3
-/* Test AST pending: */
- lwz %r5,FRAME_SRR1+8(%r1)
- mtcr %r5
- bf 17,1f /* branch if PSL_PR is false */
-
- GET_CPUINFO(%r3) /* get per-CPU pointer */
- lwz %r4, PC_CURTHREAD(%r3) /* deref to get curthread */
- lwz %r4, TD_FLAGS(%r4) /* get thread flags value */
- lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
- ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
- and. %r4,%r4,%r5
- beq 1f
- mfmsr %r3 /* re-enable interrupts */
- ori %r3,%r3,PSL_EE@l
- mtmsr %r3
- isync
- addi %r3,%r1,8
- bl CNAME(ast)
- .globl CNAME(asttrapexit) /* backtrace code sentinel #2 */
-CNAME(asttrapexit):
- b trapexit /* test ast ret value ? */
-1:
- FRAME_LEAVE(PC_TEMPSAVE)
- rfi
-
-/*
- * Temporary: vector-unavailable traps are directed to vector-assist traps
- */
- .globl CNAME(vectrap),CNAME(vectrapsize)
-CNAME(vectrap):
- ba EXC_VECAST
-CNAME(vectrapsize) = .-CNAME(vectrap)
-
-#if defined(KDB)
-/*
- * Deliberate entry to dbtrap
- */
- .globl CNAME(ppc_db_trap)
-CNAME(ppc_db_trap):
- mtsprg1 %r1
- mfmsr %r3
- mtsrr1 %r3
- andi. %r3,%r3,~(PSL_EE|PSL_ME)@l
- mtmsr %r3 /* disable interrupts */
- isync
- GET_CPUINFO(%r3)
- stw %r28,(PC_DBSAVE+CPUSAVE_R28)(%r3)
- stw %r29,(PC_DBSAVE+CPUSAVE_R29)(%r3)
- stw %r30,(PC_DBSAVE+CPUSAVE_R30)(%r3)
- stw %r31,(PC_DBSAVE+CPUSAVE_R31)(%r3)
- mflr %r28
- li %r29,EXC_BPT
- mtlr %r29
- mfcr %r29
- mtsrr0 %r28
-
-/*
- * Now the kdb trap catching code.
- */
-dbtrap:
- FRAME_SETUP(PC_DBSAVE)
-/* Call C trap code: */
- addi %r3,%r1,8
- bl CNAME(db_trap_glue)
- or. %r3,%r3,%r3
- bne dbleave
-/* This wasn't for KDB, so switch to real trap: */
- lwz %r3,FRAME_EXC+8(%r1) /* save exception */
- GET_CPUINFO(%r4)
- stw %r3,(PC_DBSAVE+CPUSAVE_R31)(%r4)
- FRAME_LEAVE(PC_DBSAVE)
- mtsprg1 %r1 /* prepare for entrance to realtrap */
- GET_CPUINFO(%r1)
- stw %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1)
- stw %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1)
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1)
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1)
- mflr %r28
- mfcr %r29
- lwz %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1)
- mtlr %r31
- mfsprg1 %r1
- b realtrap
-dbleave:
- FRAME_LEAVE(PC_DBSAVE)
- rfi
-
-/*
- * In case of KDB we want a separate trap catcher for it
- */
- .globl CNAME(dblow),CNAME(dbsize)
-CNAME(dblow):
- mtsprg1 %r1 /* save SP */
- mtsprg2 %r29 /* save r29 */
- mfcr %r29 /* save CR in r29 */
- mfsrr1 %r1
- mtcr %r1
- GET_CPUINFO(%r1)
- bf 17,1f /* branch if privileged */
- stw %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) /* free r28 */
- mfsprg2 %r28 /* r29 holds cr ... */
- stw %r28,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) /* free r29 */
- stw %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) /* free r30 */
- stw %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) /* free r31 */
- mflr %r28 /* save LR */
- bla u_trap
-1:
- stw %r28,(PC_DBSAVE+CPUSAVE_R28)(%r1) /* free r28 */
- mfsprg2 %r28 /* r29 holds cr... */
- stw %r28,(PC_DBSAVE+CPUSAVE_R29)(%r1) /* free r29 */
- stw %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */
- stw %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */
- mflr %r28 /* save LR */
- lis %r1,dbstk+INTSTK@ha /* get new SP */
- addi %r1,%r1,dbstk+INTSTK@l
- bla dbtrap
-CNAME(dbsize) = .-CNAME(dblow)
-#endif /* KDB */
diff --git a/sys/powerpc/powerpc/uio_machdep.c b/sys/powerpc/powerpc/uio_machdep.c
deleted file mode 100644
index 070ad98..0000000
--- a/sys/powerpc/powerpc/uio_machdep.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*-
- * Copyright (c) 2004 Alan L. Cox <alc@cs.rice.edu>
- * Copyright (c) 1982, 1986, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * 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.
- * 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.
- *
- * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/uio.h>
-
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-
-#include <machine/md_var.h>
-#include <machine/vmparam.h>
-
-/*
- * Implement uiomove(9) from physical memory using the direct map to
- * avoid the creation and destruction of ephemeral mappings.
- */
-int
-uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
-{
- struct thread *td = curthread;
- struct iovec *iov;
- void *cp;
- vm_offset_t page_offset;
- size_t cnt;
- int error = 0;
- int save = 0;
-
- KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
- ("uiomove_fromphys: mode"));
- KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
- ("uiomove_fromphys proc"));
- save = td->td_pflags & TDP_DEADLKTREAT;
- td->td_pflags |= TDP_DEADLKTREAT;
- while (n > 0 && uio->uio_resid) {
- iov = uio->uio_iov;
- cnt = iov->iov_len;
- if (cnt == 0) {
- uio->uio_iov++;
- uio->uio_iovcnt--;
- continue;
- }
- if (cnt > n)
- cnt = n;
- page_offset = offset & PAGE_MASK;
- cnt = min(cnt, PAGE_SIZE - page_offset);
- cp = (char *)VM_PAGE_TO_PHYS(ma[offset >> PAGE_SHIFT]) +
- page_offset;
- switch (uio->uio_segflg) {
- case UIO_USERSPACE:
- if (ticks - PCPU_GET(switchticks) >= hogticks)
- uio_yield();
- if (uio->uio_rw == UIO_READ)
- error = copyout(cp, iov->iov_base, cnt);
- else
- error = copyin(iov->iov_base, cp, cnt);
- if (error)
- goto out;
- if (uio->uio_rw == UIO_WRITE &&
- pmap_page_executable(ma[offset >> PAGE_SHIFT]))
- __syncicache(cp, cnt);
- break;
- case UIO_SYSSPACE:
- if (uio->uio_rw == UIO_READ)
- bcopy(cp, iov->iov_base, cnt);
- else
- bcopy(iov->iov_base, cp, cnt);
- break;
- case UIO_NOCOPY:
- break;
- }
- iov->iov_base = (char *)iov->iov_base + cnt;
- iov->iov_len -= cnt;
- uio->uio_resid -= cnt;
- uio->uio_offset += cnt;
- offset += cnt;
- n -= cnt;
- }
-out:
- if (save == 0)
- td->td_pflags &= ~TDP_DEADLKTREAT;
- return (error);
-}
diff --git a/sys/powerpc/powerpc/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c
deleted file mode 100644
index 89d092a..0000000
--- a/sys/powerpc/powerpc/uma_machdep.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * Copyright (c) 2003 The FreeBSD Project
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pageout.h>
-#include <vm/uma.h>
-#include <vm/uma_int.h>
-#include <machine/vmparam.h>
-
-static int hw_uma_mdpages;
-SYSCTL_INT(_hw, OID_AUTO, uma_mdpages, CTLFLAG_RD, &hw_uma_mdpages, 0,
- "UMA MD pages in use");
-
-void *
-uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
-{
- static vm_pindex_t color;
- void *va;
- vm_page_t m;
- int pflags;
-
- *flags = UMA_SLAB_PRIV;
- if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
- pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED;
- else
- pflags = VM_ALLOC_SYSTEM | VM_ALLOC_WIRED;
- if (wait & M_ZERO)
- pflags |= VM_ALLOC_ZERO;
-
- for (;;) {
- m = vm_page_alloc(NULL, color++, pflags | VM_ALLOC_NOOBJ);
- if (m == NULL) {
- if (wait & M_NOWAIT)
- return (NULL);
- VM_WAIT;
- } else
- break;
- }
-
- va = (void *) VM_PAGE_TO_PHYS(m);
- if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
- bzero(va, PAGE_SIZE);
- atomic_add_int(&hw_uma_mdpages, 1);
-
- return (va);
-}
-
-void
-uma_small_free(void *mem, int size, u_int8_t flags)
-{
- vm_page_t m;
-
- m = PHYS_TO_VM_PAGE((u_int32_t)mem);
- m->wire_count--;
- vm_page_free(m);
- atomic_subtract_int(&cnt.v_wire_count, 1);
- atomic_subtract_int(&hw_uma_mdpages, 1);
-}
diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c
deleted file mode 100644
index ce8416a..0000000
--- a/sys/powerpc/powerpc/vm_machdep.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986 The Regents of the University of California.
- * Copyright (c) 1989, 1990 William Jolitz
- * Copyright (c) 1994 John Dyson
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
- * 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: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
- * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $FreeBSD$
- */
-/*-
- * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/vnode.h>
-#include <sys/vmmeter.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/sf_buf.h>
-#include <sys/sysctl.h>
-#include <sys/unistd.h>
-
-#include <machine/cpu.h>
-#include <machine/fpu.h>
-#include <machine/frame.h>
-#include <machine/md_var.h>
-#include <machine/pcb.h>
-#include <machine/powerpc.h>
-
-#include <dev/ofw/openfirm.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_extern.h>
-
-/*
- * Finish a fork operation, with process p2 nearly set up.
- * Copy and update the pcb, set up the stack so that the child
- * ready to run and return to user mode.
- */
-void
-cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
-{
- struct proc *p1;
- struct trapframe *tf;
- struct callframe *cf;
- struct pcb *pcb;
-
- KASSERT(td1 == curthread || td1 == &thread0,
- ("cpu_fork: p1 not curproc and not proc0"));
- CTR3(KTR_PROC, "cpu_fork: called td1=%08x p2=%08x flags=%x", (u_int)td1, (u_int)p2, flags);
-
- if ((flags & RFPROC) == 0)
- return;
-
- p1 = td1->td_proc;
-
- pcb = (struct pcb *)((td2->td_kstack +
- td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fU);
- td2->td_pcb = pcb;
-
- /* Copy the pcb */
- bcopy(td1->td_pcb, pcb, sizeof(struct pcb));
-
- /*
- * Create a fresh stack for the new process.
- * Copy the trap frame for the return to user mode as if from a
- * syscall. This copies most of the user mode register values.
- */
- tf = (struct trapframe *)pcb - 1;
- bcopy(td1->td_frame, tf, sizeof(*tf));
-
- /* Set up trap frame. */
- tf->fixreg[FIRSTARG] = 0;
- tf->fixreg[FIRSTARG + 1] = 0;
- tf->cr &= ~0x10000000;
-
- td2->td_frame = tf;
-
- cf = (struct callframe *)tf - 1;
- memset(cf, 0, sizeof(struct callframe));
- cf->cf_func = (register_t)fork_return;
- cf->cf_arg0 = (register_t)td2;
- cf->cf_arg1 = (register_t)tf;
-
- pcb->pcb_sp = (register_t)cf;
- pcb->pcb_lr = (register_t)fork_trampoline;
- pcb->pcb_usr = kernel_pmap->pm_sr[USER_SR];
-
- /* Setup to release spin count in fork_exit(). */
- td2->td_md.md_spinlock_count = 1;
- td2->td_md.md_saved_msr = PSL_KERNSET;
-
- /*
- * Now cpu_switch() can schedule the new process.
- */
-}
-
-/*
- * Intercept the return address from a freshly forked process that has NOT
- * been scheduled yet.
- *
- * This is needed to make kernel threads stay in kernel mode.
- */
-void
-cpu_set_fork_handler(td, func, arg)
- struct thread *td;
- void (*func)(void *);
- void *arg;
-{
- struct callframe *cf;
-
- CTR3(KTR_PROC, "cpu_set_fork_handler: called with td=%08x func=%08x arg=%08x",
- (u_int)td, (u_int)func, (u_int)arg);
-
- cf = (struct callframe *)td->td_pcb->pcb_sp;
-
- cf->cf_func = (register_t)func;
- cf->cf_arg0 = (register_t)arg;
-}
-
-void
-cpu_exit(td)
- register struct thread *td;
-{
-}
-
-/* Temporary helper */
-void
-cpu_throw(struct thread *old, struct thread *new)
-{
-
- cpu_switch(old, new, old->td_lock);
- panic("cpu_throw() didn't");
-}
-
-/*
- * Reset back to firmware.
- */
-void
-cpu_reset()
-{
- OF_reboot();
-}
-
-/*
- * Allocate an sf_buf for the given vm_page. On this machine, however, there
- * is no sf_buf object. Instead, an opaque pointer to the given vm_page is
- * returned.
- */
-struct sf_buf *
-sf_buf_alloc(struct vm_page *m, int pri)
-{
-
- return ((struct sf_buf *)m);
-}
-
-/*
- * Free the sf_buf. In fact, do nothing because there are no resources
- * associated with the sf_buf.
- */
-void
-sf_buf_free(struct sf_buf *sf)
-{
-}
-
-/*
- * Software interrupt handler for queued VM system processing.
- */
-void
-swi_vm(void *dummy)
-{
-#if 0 /* XXX: Don't have busdma stuff yet */
- if (busdma_swi_pending != 0)
- busdma_swi();
-#endif
-}
-
-/*
- * Tell whether this address is in some physical memory region.
- * Currently used by the kernel coredump code in order to avoid
- * dumping the ``ISA memory hole'' which could cause indefinite hangs,
- * or other unpredictable behaviour.
- */
-
-
-int
-is_physical_memory(addr)
- vm_offset_t addr;
-{
- /*
- * stuff other tests for known memory-mapped devices (PCI?)
- * here
- */
-
- return 1;
-}
-
-/*
- * KSE functions
- */
-void
-cpu_thread_exit(struct thread *td)
-{
-}
-
-void
-cpu_thread_clean(struct thread *td)
-{
-}
-
-void
-cpu_thread_alloc(struct thread *td)
-{
- struct pcb *pcb;
-
- pcb = (struct pcb *)((td->td_kstack + td->td_kstack_pages * PAGE_SIZE -
- sizeof(struct pcb)) & ~0x2fU);
- td->td_pcb = pcb;
- td->td_frame = (struct trapframe *)pcb - 1;
-}
-
-void
-cpu_thread_free(struct thread *td)
-{
-}
-
-void
-cpu_thread_swapin(struct thread *td)
-{
-}
-
-void
-cpu_thread_swapout(struct thread *td)
-{
-}
-
-void
-cpu_set_upcall(struct thread *td, struct thread *td0)
-{
- struct pcb *pcb2;
- struct trapframe *tf;
- struct callframe *cf;
-
- pcb2 = td->td_pcb;
-
- /* Copy the upcall pcb */
- bcopy(td0->td_pcb, pcb2, sizeof(*pcb2));
-
- /* Create a stack for the new thread */
- tf = td->td_frame;
- bcopy(td0->td_frame, tf, sizeof(struct trapframe));
- tf->fixreg[FIRSTARG] = 0;
- tf->fixreg[FIRSTARG + 1] = 0;
- tf->cr &= ~0x10000000;
-
- /* Set registers for trampoline to user mode. */
- cf = (struct callframe *)tf - 1;
- memset(cf, 0, sizeof(struct callframe));
- cf->cf_func = (register_t)fork_return;
- cf->cf_arg0 = (register_t)td;
- cf->cf_arg1 = (register_t)tf;
-
- pcb2->pcb_sp = (register_t)cf;
- pcb2->pcb_lr = (register_t)fork_trampoline;
- pcb2->pcb_usr = kernel_pmap->pm_sr[USER_SR];
-
- /* Setup to release spin count in fork_exit(). */
- td->td_md.md_spinlock_count = 1;
- td->td_md.md_saved_msr = PSL_KERNSET;
-}
-
-void
-cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
- stack_t *stack)
-{
- struct trapframe *tf;
- uint32_t sp;
-
- tf = td->td_frame;
- /* align stack and alloc space for frame ptr and saved LR */
- sp = ((uint32_t)stack->ss_sp + stack->ss_size
- - 2*sizeof(u_int32_t)) & ~0x1f;
- bzero(tf, sizeof(struct trapframe));
-
- tf->fixreg[1] = (register_t)sp;
- tf->fixreg[3] = (register_t)arg;
- tf->srr0 = (register_t)entry;
- tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
- td->td_pcb->pcb_flags = 0;
-
- td->td_retval[0] = (register_t)entry;
- td->td_retval[1] = 0;
-}
-
-int
-cpu_set_user_tls(struct thread *td, void *tls_base)
-{
-
- td->td_frame->fixreg[2] = (register_t)tls_base + 0x7008;
- return (0);
-}
OpenPOWER on IntegriCloud