-/* $OpenBSD: autoconf.c,v 1.9 1997/10/02 19:54:14 niklas Exp $ */
-/* $NetBSD: autoconf.c,v 1.25 1997/03/22 12:51:00 ragge Exp $ */
+/* $OpenBSD: autoconf.c,v 1.10 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: autoconf.c,v 1.45 1999/10/23 14:56:05 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
#include <machine/ka750.h>
#include <machine/ka650.h>
#include <machine/clock.h>
+#include <machine/rpb.h>
+
+#include "sd.h"
+#include "cd.h"
#include <vax/vax/gencons.h>
+#include <vax/bi/bireg.h>
+
+void gencnslask __P((void));
+
struct cpu_dep *dep_call;
-struct nexus *nexus;
int mastercpu; /* chief of the system */
struct device *booted_from;
-#define BACKPLANE 0
+extern int cold; /* cold-start flag */
+
+#define MAINBUS 0
void
configure()
{
extern int boothowto;
+ if (config_rootfound("mainbus", NULL) == NULL)
+ panic("mainbus not configured");
- if (config_rootfound("backplane", NULL) == NULL)
- panic("backplane not configured");
+ setroot();
+ /*
+ * Configure swap area and related system
+ * parameter based on device(s) used.
+ */
+ swapconf();
+ cpu_dumpconf();
-#if GENERIC
- if ((boothowto & RB_ASKNAME) == 0)
- setroot();
- setconf();
-#else
- setroot();
-#endif
/*
- * Configure swap area and related system
- * parameter based on device(s) used.
+ * We're ready to start up. Clear CPU cold start flag.
*/
- swapconf();
- dumpconf();
+
cold = 0;
- mtpr(GC_CCF, PR_TXDB); /* Clear cold start flag in cpu */
+
+ if (mountroot == NULL) {
+ if (B_TYPE(bootdev) >= BDEV_NET)
+ mountroot = nfs_mountroot;
+ else
+ mountroot = dk_mountroot;
+ }
+
+ if (dep_call->cpu_clrf)
+ (*dep_call->cpu_clrf)();
}
-int printut __P((void *, const char *));
-int backplane_match __P((struct device *, void *, void *));
-void backplane_attach __P((struct device *, struct device *, void *));
+int mainbus_print __P((void *, const char *));
+int mainbus_match __P((struct device *, struct cfdata *, void *));
+void mainbus_attach __P((struct device *, struct device *, void *));
int
-printut(aux, msg)
+mainbus_print(aux, hej)
void *aux;
- const char *msg;
+ const char *hej;
{
- struct bp_conf *bp = aux;
-
- if (msg)
- printf("printut %s %s %d\n", msg, bp->type, bp->num);
- return (UNSUPP);
+ if (hej)
+ printf("nothing at %s", hej);
+ return (UNCONF);
}
int
-backplane_match(parent, gcf, aux)
+mainbus_match(parent, cf, aux)
struct device *parent;
- void *gcf, *aux;
+ struct cfdata *cf;
+ void *aux;
{
- struct cfdata *cf = gcf;
-
if (cf->cf_unit == 0 &&
- strcmp(cf->cf_driver->cd_name, "backplane") == 0)
- return 1; /* First (and only) backplane */
+ strcmp(cf->cf_driver->cd_name, "mainbus") == 0)
+ return 1; /* First (and only) mainbus */
return (0);
}
-static void find_sbi __P((struct device *, struct bp_conf *,
- int (*) __P((void *, const char *))));
-
-
void
-backplane_attach(parent, self, hej)
+mainbus_attach(parent, self, hej)
struct device *parent, *self;
void *hej;
{
- struct bp_conf bp;
-
printf("\n");
- bp.partyp = BACKPLANE;
-
- if (vax_bustype & VAX_CPUBUS) {
- bp.type = "cpu";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
- if (vax_bustype & VAX_VSBUS) {
- bp.type = "vsbus";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
- if (vax_bustype & VAX_SBIBUS) {
- bp.type = "sbi";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
- if (vax_bustype & VAX_CMIBUS) {
- bp.type = "cmi";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
- if (vax_bustype & VAX_UNIBUS) {
- bp.type = "uba";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
-#if VAX8600
- if (vax_bustype & VAX_MEMBUS) {
- bp.type = "mem";
- bp.num = 0;
- config_found(self, &bp, printut);
- }
- if (vax_cputype == VAX_8600)
- find_sbi(self, &bp, printut);
-#endif
-
-#if VAX8200 || VAX8800
- bp.type = "bi";
- if (vax_bustype & VAX_BIBUS) {
-
- switch (vax_cputype) {
-#if VAX8200
- case VAX_8200: {
- extern void *bi_nodebase;
-
- bp.bp_addr = (int)bi_nodebase;
- config_found(self, &bp, printut);
- break;
- }
-#endif
-#ifdef notyet
- case VAX_8800: {
- int bi, biaddr;
-
- for (bi = 0; bi < MAXNBI; bi++) {
- biaddr = BI_BASE(bi) + BI_PROBE;
- if (badaddr((caddr_t)biaddr, 4))
- continue;
-
- bp.bp_addr = BI_BASE(bi);
- config_found(self, &bp, printut);
- }
- break;
- }
-#endif
- }
- }
-#endif
-
-}
-
-#if VAX8600
-void
-find_sbi(self, bp, print)
- struct device *self;
- struct bp_conf *bp;
- int (*print) __P((void *, const char *));
-{
- volatile int tmp;
- volatile struct sbia_regs *sbiar;
- extern struct ioa *ioa;
- int type, i;
-
- for (i = 0; i < MAXNIOA; i++) {
- if (badaddr((caddr_t)&ioa[i], 4))
- continue;
- tmp = ioa[i].ioacsr.ioa_csr;
- type = tmp & IOA_TYPMSK;
-
- switch (type) {
-
- case IOA_SBIA:
- bp->type = "sbi";
- bp->num = i;
- config_found(self, bp, printut);
- sbiar = (void *)&ioa[i];
- sbiar->sbi_errsum = -1;
- sbiar->sbi_error = 0x1000;
- sbiar->sbi_fltsts = 0xc0000;
- break;
-
- default:
- printf("IOAdapter %x unsupported\n", type);
- break;
- }
- }
-}
-#endif
-
-int cpu_match __P((struct device *, void *, void *));
-void cpu_attach __P((struct device *, struct device *, void *));
-
-
-int
-cpu_match(parent, gcf, aux)
- struct device *parent;
- void *gcf, *aux;
-{
- struct cfdata *cf = gcf;
- struct bp_conf *bp = aux;
-
- if (strcmp(bp->type, "cpu"))
- return 0;
-
- switch (vax_cputype) {
-#if VAX750 || VAX630 || VAX650 || VAX780 || VAX8600 || VAX410
- case VAX_750:
- case VAX_78032:
- case VAX_650:
- case VAX_780:
- case VAX_8600:
- default:
- if(cf->cf_unit == 0 && bp->partyp == BACKPLANE)
- return 1;
- break;
-#endif
- };
-
- return 0;
-}
-
-void
-cpu_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- (*dep_call->cpu_conf)(parent, self, aux);
-}
-
-int mem_match __P((struct device *, void *, void *));
-void mem_attach __P((struct device *, struct device *, void *));
-
-int
-mem_match(parent, gcf, aux)
- struct device *parent;
- void *gcf, *aux;
-{
- struct cfdata *cf = gcf;
- struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
- struct bp_conf *bp = aux;
-
-#if VAX8600
- if (vax_cputype == VAX_8600 && !strcmp(parent->dv_xname, "backplane0")) {
- if (strcmp(bp->type, "mem"))
- return 0;
- return 1;
- }
-#endif
- if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1))
- return 0;
-
- switch (sa->type) {
- case NEX_MEM4:
- case NEX_MEM4I:
- case NEX_MEM16:
- case NEX_MEM16I:
- sa->nexinfo = M780C;
- break;
- case NEX_MEM64I:
- case NEX_MEM64L:
- case NEX_MEM64LI:
- case NEX_MEM256I:
- case NEX_MEM256L:
- case NEX_MEM256LI:
- sa->nexinfo = M780EL;
- break;
-
- case NEX_MEM64U:
- case NEX_MEM64UI:
- case NEX_MEM256U:
- case NEX_MEM256UI:
- sa->nexinfo = M780EU;
- break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-void
-mem_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
- struct mem_softc *sc = (void *)self;
+ /*
+ * Hopefully there a master bus?
+ * Maybe should have this as master instead of mainbus.
+ */
+ config_found(self, NULL, mainbus_print);
-#if VAX8600
- if (vax_cputype == VAX_8600) {
- ka86_memenable(0, 0);
- printf("\n");
- return;
- }
-#endif
- sc->sc_memaddr = sa->nexaddr;
- sc->sc_memtype = sa->nexinfo;
- sc->sc_memnr = sa->type;
-#ifdef VAX780
- ka780_memenable(sa, sc);
-#endif
+ if (dep_call->cpu_subconf)
+ (*dep_call->cpu_subconf)(self);
}
-struct cfdriver backplane_cd = {
- NULL, "backplane", DV_DULL
-};
-
-struct cfattach backplane_ca = {
- sizeof(struct device), backplane_match, backplane_attach
-};
-
-struct cfdriver cpu_cd = {
- NULL, "cpu", DV_CPU
+struct cfattach mainbus_ca = {
+ sizeof(struct device), (cfmatch_t) mainbus_match, mainbus_attach
};
-struct cfattach cpu_backplane_ca = {
- sizeof(struct device), cpu_match, cpu_attach
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL
};
-struct cfdriver mem_cd = {
- NULL, "mem", DV_CPU
-};
-struct cfattach mem_backplane_ca = {
- sizeof(struct mem_softc), mem_match, mem_attach
-};
-
-struct cfattach mem_sbi_ca = {
- sizeof(struct mem_softc), mem_match, mem_attach
-};
--- /dev/null
+/* $OpenBSD: bus_dma.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: bus_dma.c,v 1.5 1999/11/13 00:32:20 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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.
+ */
+/*
+ * bus_dma routines for vax. File copied from arm32/bus_dma.c.
+ * NetBSD: bus_dma.c,v 1.11 1998/09/21 22:53:35 thorpej Exp
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/map.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+#include <sys/reboot.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+
+#include <uvm/uvm_extern.h>
+
+#define _VAX_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <machine/ka43.h>
+#include <machine/sid.h>
+
+extern vaddr_t avail_start, avail_end, virtual_avail;
+
+int _bus_dmamap_load_buffer __P((bus_dma_tag_t, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int, vm_offset_t *, int *, int));
+int _bus_dma_inrange __P((bus_dma_segment_t *, int, bus_addr_t));
+int _bus_dmamem_alloc_range __P((bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t*, int, int *, int, vaddr_t, vaddr_t));
+/*
+ * Common function for DMA map creation. May be called by bus-specific
+ * DMA map creation functions.
+ */
+int
+_bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, flags, dmamp)
+ bus_dma_tag_t t;
+ bus_size_t size;
+ int nsegments;
+ bus_size_t maxsegsz;
+ bus_size_t boundary;
+ int flags;
+ bus_dmamap_t *dmamp;
+{
+ struct vax_bus_dmamap *map;
+ void *mapstore;
+ size_t mapsize;
+
+#ifdef DEBUG_DMA
+ printf("dmamap_create: t=%p size=%lx nseg=%x msegsz=%lx boundary=%lx flags=%x\n",
+ t, size, nsegments, maxsegsz, boundary, flags);
+#endif /* DEBUG_DMA */
+
+ /*
+ * Allocate and initialize the DMA map. The end of the map
+ * is a variable-sized array of segments, so we allocate enough
+ * room for them in one shot.
+ *
+ * Note we don't preserve the WAITOK or NOWAIT flags. Preservation
+ * of ALLOCNOW notifies others that we've reserved these resources,
+ * and they are not to be freed.
+ *
+ * The bus_dmamap_t includes one bus_dma_segment_t, hence
+ * the (nsegments - 1).
+ */
+ mapsize = sizeof(struct vax_bus_dmamap) +
+ (sizeof(bus_dma_segment_t) * (nsegments - 1));
+ if ((mapstore = malloc(mapsize, M_DEVBUF,
+ (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
+ return (ENOMEM);
+
+ bzero(mapstore, mapsize);
+ map = (struct vax_bus_dmamap *)mapstore;
+ map->_dm_size = size;
+ map->_dm_segcnt = nsegments;
+ map->_dm_maxsegsz = maxsegsz;
+ map->_dm_boundary = boundary;
+ map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
+ map->dm_mapsize = 0; /* no valid mappings */
+ map->dm_nsegs = 0;
+
+ *dmamp = map;
+#ifdef DEBUG_DMA
+ printf("dmamap_create:map=%p\n", map);
+#endif /* DEBUG_DMA */
+ return (0);
+}
+
+/*
+ * Common function for DMA map destruction. May be called by bus-specific
+ * DMA map destruction functions.
+ */
+void
+_bus_dmamap_destroy(t, map)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+{
+
+#ifdef DEBUG_DMA
+ printf("dmamap_destroy: t=%p map=%p\n", t, map);
+#endif /* DEBUG_DMA */
+#ifdef DIAGNOSTIC
+ if (map->dm_nsegs > 0)
+ printf("bus_dmamap_destroy() called for map with valid mappings\n");
+#endif /* DIAGNOSTIC */
+ free(map, M_DEVBUF);
+}
+
+/*
+ * Common function for loading a DMA map with a linear buffer. May
+ * be called by bus-specific DMA map load functions.
+ */
+int
+_bus_dmamap_load(t, map, buf, buflen, p, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ void *buf;
+ bus_size_t buflen;
+ struct proc *p;
+ int flags;
+{
+ vm_offset_t lastaddr;
+ int seg, error;
+
+#ifdef DEBUG_DMA
+ printf("dmamap_load: t=%p map=%p buf=%p len=%lx p=%p f=%d\n",
+ t, map, buf, buflen, p, flags);
+#endif /* DEBUG_DMA */
+
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+ if (buflen > map->_dm_size)
+ return (EINVAL);
+
+ seg = 0;
+ error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
+ &lastaddr, &seg, 1);
+ if (error == 0) {
+ map->dm_mapsize = buflen;
+ map->dm_nsegs = seg + 1;
+ }
+#ifdef DEBUG_DMA
+ printf("dmamap_load: error=%d\n", error);
+#endif /* DEBUG_DMA */
+ return (error);
+}
+
+/*
+ * Like _bus_dmamap_load(), but for mbufs.
+ */
+int
+_bus_dmamap_load_mbuf(t, map, m0, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct mbuf *m0;
+ int flags;
+{
+ vm_offset_t lastaddr;
+ int seg, error, first;
+ struct mbuf *m;
+
+#ifdef DEBUG_DMA
+ printf("dmamap_load_mbuf: t=%p map=%p m0=%p f=%d\n",
+ t, map, m0, flags);
+#endif /* DEBUG_DMA */
+
+ /*
+ * Make sure that on error condition we return "no valid mappings."
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+#ifdef DIAGNOSTIC
+ if ((m0->m_flags & M_PKTHDR) == 0)
+ panic("_bus_dmamap_load_mbuf: no packet header");
+#endif /* DIAGNOSTIC */
+
+ if (m0->m_pkthdr.len > map->_dm_size)
+ return (EINVAL);
+
+ first = 1;
+ seg = 0;
+ error = 0;
+ for (m = m0; m != NULL && error == 0; m = m->m_next) {
+ error = _bus_dmamap_load_buffer(t, map, m->m_data, m->m_len,
+ NULL, flags, &lastaddr, &seg, first);
+ first = 0;
+ }
+ if (error == 0) {
+ map->dm_mapsize = m0->m_pkthdr.len;
+ map->dm_nsegs = seg + 1;
+ }
+#ifdef DEBUG_DMA
+ printf("dmamap_load_mbuf: error=%d\n", error);
+#endif /* DEBUG_DMA */
+ return (error);
+}
+
+/*
+ * Like _bus_dmamap_load(), but for uios.
+ */
+int
+_bus_dmamap_load_uio(t, map, uio, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct uio *uio;
+ int flags;
+{
+ vm_offset_t lastaddr;
+ int seg, i, error, first;
+ bus_size_t minlen, resid;
+ struct proc *p = NULL;
+ struct iovec *iov;
+ caddr_t addr;
+
+ /*
+ * Make sure that on error condition we return "no valid mappings."
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+ resid = uio->uio_resid;
+ iov = uio->uio_iov;
+
+ if (uio->uio_segflg == UIO_USERSPACE) {
+ p = uio->uio_procp;
+#ifdef DIAGNOSTIC
+ if (p == NULL)
+ panic("_bus_dmamap_load_uio: USERSPACE but no proc");
+#endif
+ }
+
+ first = 1;
+ seg = 0;
+ error = 0;
+ for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
+ /*
+ * Now at the first iovec to load. Load each iovec
+ * until we have exhausted the residual count.
+ */
+ minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
+ addr = (caddr_t)iov[i].iov_base;
+
+ error = _bus_dmamap_load_buffer(t, map, addr, minlen,
+ p, flags, &lastaddr, &seg, first);
+ first = 0;
+
+ resid -= minlen;
+ }
+ if (error == 0) {
+ map->dm_mapsize = uio->uio_resid;
+ map->dm_nsegs = seg + 1;
+ }
+ return (error);
+}
+
+/*
+ * Like _bus_dmamap_load(), but for raw memory allocated with
+ * bus_dmamem_alloc().
+ */
+int
+_bus_dmamap_load_raw(t, map, segs, nsegs, size, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ bus_size_t size;
+ int flags;
+{
+
+ panic("_bus_dmamap_load_raw: not implemented");
+}
+
+/*
+ * Common function for unloading a DMA map. May be called by
+ * bus-specific DMA map unload functions.
+ */
+void
+_bus_dmamap_unload(t, map)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+{
+
+#ifdef DEBUG_DMA
+ printf("dmamap_unload: t=%p map=%p\n", t, map);
+#endif /* DEBUG_DMA */
+
+ /*
+ * No resources to free; just mark the mappings as
+ * invalid.
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+}
+
+/*
+ * Common function for DMA map synchronization. May be called
+ * by bus-specific DMA map synchronization functions.
+ */
+void
+_bus_dmamap_sync(t, map, offset, len, ops)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ bus_addr_t offset;
+ bus_size_t len;
+ int ops;
+{
+#ifdef DEBUG_DMA
+ printf("dmamap_sync: t=%p map=%p offset=%lx len=%lx ops=%x\n",
+ t, map, offset, len, ops);
+#endif /* DEBUG_DMA */
+ /*
+ * A vax only has snoop-cache, so this routine is a no-op.
+ */
+ return;
+}
+
+/*
+ * Common function for DMA-safe memory allocation. May be called
+ * by bus-specific DMA memory allocation functions.
+ */
+
+int
+_bus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
+ bus_dma_tag_t t;
+ bus_size_t size, alignment, boundary;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ int *rsegs;
+ int flags;
+{
+ int error;
+
+ error = (_bus_dmamem_alloc_range(t, size, alignment, boundary,
+ segs, nsegs, rsegs, flags, round_page(avail_start),
+ trunc_page(avail_end)));
+ return(error);
+}
+
+/*
+ * Common function for freeing DMA-safe memory. May be called by
+ * bus-specific DMA memory free functions.
+ */
+void
+_bus_dmamem_free(t, segs, nsegs)
+ bus_dma_tag_t t;
+ bus_dma_segment_t *segs;
+ int nsegs;
+{
+ vm_page_t m;
+ bus_addr_t addr;
+ struct pglist mlist;
+ int curseg;
+
+#ifdef DEBUG_DMA
+ printf("dmamem_free: t=%p segs=%p nsegs=%x\n", t, segs, nsegs);
+#endif /* DEBUG_DMA */
+
+ /*
+ * Build a list of pages to free back to the VM system.
+ */
+ TAILQ_INIT(&mlist);
+ for (curseg = 0; curseg < nsegs; curseg++) {
+ for (addr = segs[curseg].ds_addr;
+ addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
+ addr += PAGE_SIZE) {
+ m = PHYS_TO_VM_PAGE(addr);
+ TAILQ_INSERT_TAIL(&mlist, m, pageq);
+ }
+ }
+ uvm_pglistfree(&mlist);
+}
+
+/*
+ * Common function for mapping DMA-safe memory. May be called by
+ * bus-specific DMA memory map functions.
+ */
+int
+_bus_dmamem_map(t, segs, nsegs, size, kvap, flags)
+ bus_dma_tag_t t;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ size_t size;
+ caddr_t *kvap;
+ int flags;
+{
+ vm_offset_t va;
+ bus_addr_t addr;
+ int curseg;
+
+ /*
+ * Special case (but common):
+ * If there is only one physical segment then the already-mapped
+ * virtual address is returned, since all physical memory is already
+ * in the beginning of kernel virtual memory.
+ */
+ if (nsegs == 1) {
+ *kvap = (caddr_t)(segs[0].ds_addr | KERNBASE);
+ /*
+ * KA43 (3100/m76) must have its DMA-safe memory accessed
+ * through DIAGMEM. Remap it here.
+ */
+ if (vax_boardtype == VAX_BTYP_43) {
+ pmap_map((vaddr_t)*kvap, segs[0].ds_addr|KA43_DIAGMEM,
+ (segs[0].ds_addr|KA43_DIAGMEM) + size,
+ VM_PROT_READ|VM_PROT_WRITE);
+ }
+ return 0;
+ }
+ size = round_page(size);
+ va = uvm_km_valloc(kernel_map, size);
+
+ if (va == 0)
+ return (ENOMEM);
+
+ *kvap = (caddr_t)va;
+
+ for (curseg = 0; curseg < nsegs; curseg++) {
+ for (addr = segs[curseg].ds_addr;
+ addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
+ addr += NBPG, va += NBPG, size -= NBPG) {
+ if (size == 0)
+ panic("_bus_dmamem_map: size botch");
+ if (vax_boardtype == VAX_BTYP_43)
+ addr |= KA43_DIAGMEM;
+ pmap_enter(pmap_kernel(), va, addr,
+ VM_PROT_READ | VM_PROT_WRITE, TRUE,
+ VM_PROT_READ | VM_PROT_WRITE);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Common function for unmapping DMA-safe memory. May be called by
+ * bus-specific DMA memory unmapping functions.
+ */
+void
+_bus_dmamem_unmap(t, kva, size)
+ bus_dma_tag_t t;
+ caddr_t kva;
+ size_t size;
+{
+
+#ifdef DEBUG_DMA
+ printf("dmamem_unmap: t=%p kva=%p size=%x\n", t, kva, size);
+#endif /* DEBUG_DMA */
+#ifdef DIAGNOSTIC
+ if ((u_long)kva & PGOFSET)
+ panic("_bus_dmamem_unmap");
+#endif /* DIAGNOSTIC */
+
+ /* Avoid free'ing if not mapped */
+ if (kva >= (caddr_t)virtual_avail)
+ uvm_km_free(kernel_map, (vm_offset_t)kva, round_page(size));
+}
+
+/*
+ * Common functin for mmap(2)'ing DMA-safe memory. May be called by
+ * bus-specific DMA mmap(2)'ing functions.
+ */
+int
+_bus_dmamem_mmap(t, segs, nsegs, off, prot, flags)
+ bus_dma_tag_t t;
+ bus_dma_segment_t *segs;
+ int nsegs, off, prot, flags;
+{
+ int i;
+
+ for (i = 0; i < nsegs; i++) {
+#ifdef DIAGNOSTIC
+ if (off & PGOFSET)
+ panic("_bus_dmamem_mmap: offset unaligned");
+ if (segs[i].ds_addr & PGOFSET)
+ panic("_bus_dmamem_mmap: segment unaligned");
+ if (segs[i].ds_len & PGOFSET)
+ panic("_bus_dmamem_mmap: segment size not multiple"
+ " of page size");
+#endif /* DIAGNOSTIC */
+ if (off >= segs[i].ds_len) {
+ off -= segs[i].ds_len;
+ continue;
+ }
+
+ return (btop((u_long)segs[i].ds_addr + off));
+ }
+
+ /* Page not found. */
+ return (-1);
+}
+
+/**********************************************************************
+ * DMA utility functions
+ **********************************************************************/
+
+/*
+ * Utility function to load a linear buffer. lastaddrp holds state
+ * between invocations (for multiple-buffer loads). segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ * first indicates if this is the first invocation of this function.
+ */
+int
+_bus_dmamap_load_buffer(t, map, buf, buflen, p, flags, lastaddrp, segp, first)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ void *buf;
+ bus_size_t buflen;
+ struct proc *p;
+ int flags;
+ vm_offset_t *lastaddrp;
+ int *segp;
+ int first;
+{
+ bus_size_t sgsize;
+ bus_addr_t curaddr, lastaddr, baddr, bmask;
+ vm_offset_t vaddr = (vm_offset_t)buf;
+ int seg;
+ pmap_t pmap;
+
+#ifdef DEBUG_DMA
+ printf("_bus_dmamem_load_buffer(buf=%p, len=%lx, flags=%d, 1st=%d)\n",
+ buf, buflen, flags, first);
+#endif /* DEBUG_DMA */
+
+ if (p != NULL)
+ pmap = p->p_vmspace->vm_map.pmap;
+ else
+ pmap = pmap_kernel();
+
+ lastaddr = *lastaddrp;
+ bmask = ~(map->_dm_boundary - 1);
+
+ for (seg = *segp; buflen > 0; ) {
+ /*
+ * Get the physical address for this segment.
+ */
+ curaddr = pmap_extract(pmap, (vaddr_t)vaddr);
+
+#if 0
+ /*
+ * Make sure we're in an allowed DMA range.
+ */
+ if (t->_ranges != NULL &&
+ _bus_dma_inrange(t->_ranges, t->_nranges, curaddr) == 0)
+ return (EINVAL);
+#endif
+
+ /*
+ * Compute the segment size, and adjust counts.
+ */
+ sgsize = NBPG - ((u_long)vaddr & PGOFSET);
+ if (buflen < sgsize)
+ sgsize = buflen;
+
+ /*
+ * Make sure we don't cross any boundaries.
+ */
+ if (map->_dm_boundary > 0) {
+ baddr = (curaddr + map->_dm_boundary) & bmask;
+ if (sgsize > (baddr - curaddr))
+ sgsize = (baddr - curaddr);
+ }
+
+ /*
+ * Insert chunk into a segment, coalescing with
+ * previous segment if possible.
+ */
+ if (first) {
+ map->dm_segs[seg].ds_addr = curaddr;
+ map->dm_segs[seg].ds_len = sgsize;
+ first = 0;
+ } else {
+ if (curaddr == lastaddr &&
+ (map->dm_segs[seg].ds_len + sgsize) <=
+ map->_dm_maxsegsz &&
+ (map->_dm_boundary == 0 ||
+ (map->dm_segs[seg].ds_addr & bmask) ==
+ (curaddr & bmask)))
+ map->dm_segs[seg].ds_len += sgsize;
+ else {
+ if (++seg >= map->_dm_segcnt)
+ break;
+ map->dm_segs[seg].ds_addr = curaddr;
+ map->dm_segs[seg].ds_len = sgsize;
+ }
+ }
+
+ lastaddr = curaddr + sgsize;
+ vaddr += sgsize;
+ buflen -= sgsize;
+ }
+
+ *segp = seg;
+ *lastaddrp = lastaddr;
+
+ /*
+ * Did we fit?
+ */
+ if (buflen != 0)
+ return (EFBIG); /* XXX better return value here? */
+ return (0);
+}
+
+/*
+ * Check to see if the specified page is in an allowed DMA range.
+ */
+int
+_bus_dma_inrange(ranges, nranges, curaddr)
+ bus_dma_segment_t *ranges;
+ int nranges;
+ bus_addr_t curaddr;
+{
+ bus_dma_segment_t *ds;
+ int i;
+
+ for (i = 0, ds = ranges; i < nranges; i++, ds++) {
+ if (curaddr >= ds->ds_addr &&
+ round_page(curaddr) <= (ds->ds_addr + ds->ds_len))
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Allocate physical memory from the given physical address range.
+ * Called by DMA-safe memory allocation methods.
+ */
+int
+_bus_dmamem_alloc_range(t, size, alignment, boundary, segs, nsegs, rsegs,
+ flags, low, high)
+ bus_dma_tag_t t;
+ bus_size_t size, alignment, boundary;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ int *rsegs;
+ int flags;
+ vm_offset_t low;
+ vm_offset_t high;
+{
+ vm_offset_t curaddr, lastaddr;
+ vm_page_t m;
+ struct pglist mlist;
+ int curseg, error;
+
+#ifdef DEBUG_DMA
+ printf("alloc_range: t=%p size=%lx align=%lx boundary=%lx segs=%p nsegs=%x rsegs=%p flags=%x lo=%lx hi=%lx\n",
+ t, size, alignment, boundary, segs, nsegs, rsegs, flags, low, high);
+#endif /* DEBUG_DMA */
+
+ /* Always round the size. */
+ size = round_page(size);
+
+ /*
+ * Allocate pages from the VM system.
+ */
+ TAILQ_INIT(&mlist);
+ error = uvm_pglistalloc(size, low, high, alignment, boundary,
+ &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
+ if (error)
+ return (error);
+
+ /*
+ * Compute the location, size, and number of segments actually
+ * returned by the VM code.
+ */
+ m = mlist.tqh_first;
+ curseg = 0;
+ lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m);
+ segs[curseg].ds_len = PAGE_SIZE;
+#ifdef DEBUG_DMA
+ printf("alloc: page %lx\n", lastaddr);
+#endif /* DEBUG_DMA */
+ m = m->pageq.tqe_next;
+
+ for (; m != NULL; m = m->pageq.tqe_next) {
+ curaddr = VM_PAGE_TO_PHYS(m);
+#ifdef DIAGNOSTIC
+ if (curaddr < low || curaddr >= high) {
+ printf("vm_page_alloc_memory returned non-sensical"
+ " address 0x%lx\n", curaddr);
+ panic("_bus_dmamem_alloc_range");
+ }
+#endif /* DIAGNOSTIC */
+#ifdef DEBUG_DMA
+ printf("alloc: page %lx\n", curaddr);
+#endif /* DEBUG_DMA */
+ if (curaddr == (lastaddr + PAGE_SIZE))
+ segs[curseg].ds_len += PAGE_SIZE;
+ else {
+ curseg++;
+ segs[curseg].ds_addr = curaddr;
+ segs[curseg].ds_len = PAGE_SIZE;
+ }
+ lastaddr = curaddr;
+ }
+
+ *rsegs = curseg + 1;
+
+ return (0);
+}
+
+/*
+ * "generic" DMA struct, nothing special.
+ */
+struct vax_bus_dma_tag vax_bus_dma_tag = {
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load,
+ _bus_dmamap_load_mbuf,
+ _bus_dmamap_load_uio,
+ _bus_dmamap_load_raw,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
--- /dev/null
+/* $OpenBSD: bus_mem.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: bus_mem.c,v 1.5 1999/05/24 20:10:30 ragge Exp $ */
+/*
+ * Copyright (c) 1998 Matt Thomas
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by Bertram Barth.
+ *
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/cpu.h>
+#include <machine/pmap.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+static int
+vax_mem_bus_space_map(
+ void *t,
+ bus_addr_t pa,
+ bus_size_t size,
+ int cacheable,
+ bus_space_handle_t *bshp,
+ int f2)
+{
+ vaddr_t va;
+
+ va = uvm_km_valloc(kernel_map, size);
+ if (va == 0)
+ return (ENOMEM);
+
+ *bshp = (bus_space_handle_t)(va + (pa & VAX_PGOFSET));
+
+ ioaccess(va, pa, size >> VAX_PGSHIFT);
+
+ return 0;
+}
+
+static int
+vax_mem_bus_space_subregion(
+ void *t,
+ bus_space_handle_t h,
+ bus_size_t o,
+ bus_size_t s,
+ bus_space_handle_t *hp)
+{
+ *hp = h + o;
+ return (0);
+}
+
+static void
+vax_mem_bus_space_unmap(
+ void *t,
+ bus_space_handle_t h,
+ bus_size_t size,
+ int f)
+{
+ u_long va = trunc_page(h);
+ u_long endva = round_page(h + size);
+
+ /*
+ * Free the kernel virtual mapping.
+ */
+ iounaccess(va, size >> VAX_PGSHIFT);
+ uvm_km_free(kernel_map, va, endva - va);
+}
+
+static int
+vax_mem_bus_space_alloc(
+ void *t,
+ bus_addr_t rs,
+ bus_addr_t re,
+ bus_size_t s,
+ bus_size_t a,
+ bus_size_t b,
+ int f,
+ bus_addr_t *ap,
+ bus_space_handle_t *hp)
+{
+ panic("vax_mem_bus_alloc not implemented");
+}
+
+static void
+vax_mem_bus_space_free(
+ void *t,
+ bus_space_handle_t h,
+ bus_size_t s)
+{
+ panic("vax_mem_bus_free not implemented");
+}
+
+struct vax_bus_space vax_mem_bus_space = {
+ NULL,
+ vax_mem_bus_space_map,
+ vax_mem_bus_space_unmap,
+ vax_mem_bus_space_subregion,
+ vax_mem_bus_space_alloc,
+ vax_mem_bus_space_free
+};
-/* $OpenBSD: cfl.c,v 1.1 1997/09/12 09:30:53 maja Exp $ */
-/* $NetBSD: cfl.c,v 1.1 1997/06/13 14:55:07 ragge Exp $ */
+/* $OpenBSD: cfl.c,v 1.2 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: cfl.c,v 1.2 1998/04/13 12:10:26 ragge Exp $ */
/*-
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* Copyright (c) 1982, 1986 The Regents of the University of California.
#endif
}
+void cfltint __P((int));
+
void
cfltint(arg)
int arg;
break;
case CFL_SECTOR:/* send sector */
- mtpr(FLOP_DATA | (int)bp->b_blkno % CFL_SECTORS + 1, PR_TXDB);
+ mtpr(FLOP_DATA | (int)bp->b_blkno % (CFL_SECTORS + 1), PR_TXDB);
cfltab.cfl_active = CFL_TRACK;
break;
}
}
+void cflrint __P((int));
+
void
cflrint(ch)
int ch;
-/* $OpenBSD: clock.c,v 1.9 2000/04/11 02:44:32 pjanzen Exp $ */
-/* $NetBSD: clock.c,v 1.20 1997/04/18 18:49:37 ragge Exp $ */
+/* $OpenBSD: clock.c,v 1.10 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: clock.c,v 1.28 1999/05/01 16:13:43 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
#include <machine/sid.h>
#include <machine/clock.h>
#include <machine/cpu.h>
+#include <machine/uvax.h>
-static unsigned long year; /* start of current year in seconds */
-static unsigned long year_len; /* length of current year in 100th of seconds */
+int yeartonum __P((int));
+int numtoyear __P((int));
/*
* microtime() should return number of usecs in struct timeval.
microtime(tvp)
struct timeval *tvp;
{
- u_int int_time, tmp_year;
int s, i;
static struct timeval lasttime;
s = splhigh();
- int_time = mfpr(PR_TODR);
-
- asm ("movc3 %0,(%1),(%2)"
- :
- : "r" (sizeof(struct timeval)),"r" (&time),"r"(tvp)
- :"r0","r1","r2","r3","r4","r5");
-
- i = mfpr(PR_ICR) + tick; /* Get current interval count */
+ bcopy((caddr_t)&time, tvp, sizeof(struct timeval));
+
+ switch (vax_boardtype) {
+#ifdef VAX46
+ case VAX_BTYP_46: {
+ extern struct vs_cpu *ka46_cpu;
+ i = *(volatile int *)(&ka46_cpu->vc_diagtimu);
+ i = (i >> 16) * 1024 + (i & 0x3ff);
+ break;
+ }
+#endif
+ default:
+ i = mfpr(PR_ICR);
+ break;
+ }
+ i += tick; /* Get current interval count */
tvp->tv_usec += i;
while (tvp->tv_usec >= 1000000) {
tvp->tv_sec++;
tvp->tv_usec -= 1000000;
}
bcopy(tvp, &lasttime, sizeof(struct timeval));
- if (int_time > year_len) {
- mtpr(mfpr(PR_TODR) - year_len, PR_TODR);
- year += year_len / 100;
- tmp_year = year / SEC_PER_DAY / 365 + 2;
- year_len = 100 * SEC_PER_DAY *
- ((tmp_year % 4 && tmp_year != 32) ? 365 : 366);
- }
splx(s);
}
default: /* System clock OK, no warning if we don't want to. */
if (time.tv_sec > fs_time + 3 * SEC_PER_DAY) {
- printf("Clock has gained %d days",
+ printf("Clock has gained %ld days",
(time.tv_sec - fs_time) / SEC_PER_DAY);
rv = CLKREAD_WARN;
} else if (time.tv_sec + SEC_PER_DAY < fs_time) {
- printf("Clock has lost %d day(s)",
+ printf("Clock has lost %ld day(s)",
(fs_time - time.tv_sec) / SEC_PER_DAY);
rv = CLKREAD_WARN;
}
asm ("1: sobgtr %0, 1b" : : "r" (dep_call->cpu_vups * i));
}
-#if VAX750 || VAX780 || VAX8200 || VAX8600 || VAX8800
/*
- * On most VAXen there are a microsecond clock that should
- * be used for interval interrupts. Have a generic version here.
+ * On all VAXen there are a microsecond clock that should
+ * be used for interval interrupts. Some CPUs don't use the ICR interval
+ * register but it doesn't hurt to load it anyway.
*/
void
-generic_clock()
+cpu_initclocks()
{
mtpr(-10000, PR_NICR); /* Load in count register */
mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */
}
-#endif
-
-#if VAX650 || VAX630 || VAX410 || VAX43
-/*
- * Most microvaxen don't have a interval count register.
- */
-void
-no_nicr_clock()
-{
- mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */
-}
-#endif
/*
* There are two types of real-time battery-backed up clocks on
}
#endif
-#if VAX630 || VAX410 || VAX43 || VAX8200
+#if VAX630 || VAX410 || VAX43 || VAX8200 || VAX46
volatile short *clk_page; /* where the chip is mapped in virtual memory */
int clk_adrshift; /* how much to multiply the in-page address with */
}
s = splhigh();
- c.dt_year = REGPEEK(YR_OFF) + 1970;
+ c.dt_year = ((u_char)REGPEEK(YR_OFF)) + 1970;
c.dt_mon = REGPEEK(MON_OFF);
c.dt_day = REGPEEK(DAY_OFF);
c.dt_wday = REGPEEK(WDAY_OFF);
clock_secs_to_ymdhms(time.tv_sec, &c);
- REGPOKE(YR_OFF, c.dt_year - 1970);
+ REGPOKE(YR_OFF, ((u_char)(c.dt_year - 1970)));
REGPOKE(MON_OFF, c.dt_mon);
REGPOKE(DAY_OFF, c.dt_day);
REGPOKE(WDAY_OFF, c.dt_wday);
--- /dev/null
+/* $OpenBSD: cmi.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: cmi.c,v 1.2 1999/08/14 11:30:48 ragge Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <machine/nexus.h>
+#include <machine/cpu.h>
+#include <machine/sid.h>
+#include <machine/ka750.h>
+
+static int cmi_print __P((void *, const char *));
+static int cmi_match __P((struct device *, struct cfdata *, void *));
+static void cmi_attach __P((struct device *, struct device *, void*));
+
+struct cfattach cmi_ca = {
+ sizeof(struct device), cmi_match, cmi_attach
+};
+
+int
+cmi_print(aux, name)
+ void *aux;
+ const char *name;
+{
+ struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
+
+ if (name)
+ printf("unknown device 0x%x at %s", sa->type, name);
+
+ printf(" tr%d", sa->nexnum);
+ return (UNCONF);
+}
+
+
+int
+cmi_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ if (vax_bustype == VAX_CMIBUS)
+ return 1;
+ return 0;
+}
+
+void
+cmi_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct sbi_attach_args sa;
+
+ printf("\n");
+ /*
+ * Probe for memory, can be in the first 4 slots.
+ */
+#define NEXPAGES (sizeof(struct nexus) / VAX_NBPG)
+ for (sa.nexnum = 0; sa.nexnum < 4; sa.nexnum++) {
+ sa.nexaddr = (struct nexus *)vax_map_physmem(NEX750 +
+ sizeof(struct nexus) * sa.nexnum, NEXPAGES);
+ if (badaddr((caddr_t)sa.nexaddr, 4)) {
+ vax_unmap_physmem((vaddr_t)sa.nexaddr, NEXPAGES);
+ } else {
+ sa.type = NEX_MEM16;
+ config_found(self, (void*)&sa, cmi_print);
+ }
+ }
+
+ /*
+ * Probe for mba's, can be in slot 4 - 7.
+ */
+ for (sa.nexnum = 4; sa.nexnum < 7; sa.nexnum++) {
+ sa.nexaddr = (struct nexus *)vax_map_physmem(NEX750 +
+ sizeof(struct nexus) * sa.nexnum, NEXPAGES);
+ if (badaddr((caddr_t)sa.nexaddr, 4)) {
+ vax_unmap_physmem((vaddr_t)sa.nexaddr, NEXPAGES);
+ } else {
+ sa.type = NEX_MBA;
+ config_found(self, (void*)&sa, cmi_print);
+ }
+ }
+
+ /*
+ * There are always one generic UBA, and maybe an optional.
+ */
+ sa.nexnum = 8;
+ sa.nexaddr = (struct nexus *)vax_map_physmem(NEX750 +
+ sizeof(struct nexus) * sa.nexnum, NEXPAGES);
+ sa.type = NEX_UBA0;
+ config_found(self, (void*)&sa, cmi_print);
+
+ sa.nexnum = 9;
+ sa.nexaddr = (struct nexus *)vax_map_physmem(NEX750 +
+ sizeof(struct nexus) * sa.nexnum, NEXPAGES);
+ sa.type = NEX_UBA1;
+ if (badaddr((caddr_t)sa.nexaddr, 4))
+ vax_unmap_physmem((vaddr_t)sa.nexaddr, NEXPAGES);
+ else
+ config_found(self, (void*)&sa, cmi_print);
+}
-/* $OpenBSD: conf.c,v 1.17 1998/09/25 09:20:54 todd Exp $ */
-/* $NetBSD: conf.c,v 1.28 1997/02/04 19:13:17 ragge Exp $ */
+/* $OpenBSD: conf.c,v 1.18 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: conf.c,v 1.44 1999/10/27 16:38:54 ragge Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
#include <sys/conf.h>
#include <sys/vnode.h>
+#include <vax/include/rpb.h>
+
#include "hp.h" /* 0 */
bdev_decl(hp);
#include "ra.h"
bdev_decl(ra);
+bdev_decl(rx);
#include "up.h"
bdev_decl(up);
#include "rb.h"
bdev_decl(idc);
-#include "rx.h"
-bdev_decl(rx);
-
#include "uu.h"
bdev_decl(uu);
#include "ccd.h"
bdev_decl(ccd);
+#include "raid.h"
+bdev_decl(raid);
+
#include "vnd.h"
bdev_decl(vnd);
#include "hdc.h"
-bdev_decl(hdc);
+bdev_decl(hd);
+bdev_decl(ry);
#include "sd.h"
bdev_decl(sd);
#include "cd.h"
bdev_decl(cd);
+#include "ksyms.h"
+cdev_decl(ksyms);
+
+#ifdef IPFILTER
+#define NIPF 1
+#else
+#define NIPF 0
+#endif
+
struct bdevsw bdevsw[] =
{
bdev_disk_init(NHP,hp), /* 0: RP0?/RM0? */
bdev_disk_init(NRA,ra), /* 9: MSCP disk */
bdev_tape_init(NTJ,ut), /* 10: TU45 */
bdev_disk_init(NRB,idc), /* 11: IDC (RB730) */
- bdev_disk_init(NRX,rx), /* 12: RX01/02 on unibus */
+ bdev_disk_init(NRX,rx), /* 12: RX?? on MSCP */
bdev_disk_init(NUU,uu), /* 13: TU58 on DL11 */
bdev_disk_init(NRL,rl), /* 14: RL01/02 */
bdev_tape_init(NMT,mt), /* 15: MSCP tape */
bdev_notdef(), /* 16: was: KDB50/RA?? */
bdev_disk_init(NCCD,ccd), /* 17: concatenated disk driver */
bdev_disk_init(NVND,vnd), /* 18: vnode disk driver */
- bdev_disk_init(NHDC,hdc), /* 19: HDC9224/RD?? */
+ bdev_disk_init(NHD,hd), /* 19: VS3100 ST506 disk */
bdev_disk_init(NSD,sd), /* 20: SCSI disk */
bdev_tape_init(NST,st), /* 21: SCSI tape */
bdev_disk_init(NCD,cd), /* 22: SCSI CD-ROM */
- bdev_notdef(), /* 23: was: memory disk driver */
+ bdev_notdef(), /* 23: was: memory disk driver */
+ bdev_disk_init(NRY,ry), /* 24: VS3100 floppy */
+ bdev_disk_init(NRAID,raid), /* 25: RAIDframe disk driver */
};
int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
+struct bdevmajtpl {
+ int bdev;
+ int maj;
+} bdevtpls[] = {
+ { BDEV_HP, 0 },
+ { BDEV_RK, 3 },
+ { BDEV_IDC, 11 },
+ { BDEV_RL, 14 },
+ { BDEV_KDB, 16 },
+ { BDEV_RD, 19 },
+ { BDEV_SD, 20 },
+ { BDEV_ST, 21 },
+
+ /* some things need these network devices, do not change them */
+ { BDEV_QE, BDEV_QE },
+ { BDEV_DE, BDEV_DE },
+ { BDEV_NI, BDEV_NI },
+ { BDEV_LE, BDEV_LE },
+ { BDEV_ZE, BDEV_ZE },
+
+ { -1, -1 }
+};
+
+/*
+ * BDEV_* -> major table (for bootable block devices)
+ */
+int bdevtomaj (bdev)
+ int bdev;
+{
+ struct bdevmajtpl *bd;
+
+ for(bd = bdevtpls; bd; bd++) {
+ if(bdev == bd->bdev || bd->bdev == -1)
+ return bd->maj;
+ }
+}
+
/*
* Console routines for VAX console.
*/
#include <dev/cons.h>
-#define gencnpollc nullcnpollc
+#include "lkc.h"
+#if NLKC
+#define smgcngetc lkccngetc
+#else
+#define smgcngetc nullcngetc
+#endif
+
+#define smgcnputc wsdisplay_cnputc
+#define smgcnpollc nullcnpollc
+
cons_decl(gen);
-#define dzcnpollc nullcnpollc
cons_decl(dz);
+cons_decl(qd);
+cons_decl(smg);
+#include "qv.h"
+#include "qd.h"
+#include "smg.h"
struct consdev constab[]={
-#if VAX8600 || VAX780 || VAX750 || VAX650 || VAX630
+#if VAX8600 || VAX8200 || VAX780 || VAX750 || VAX650 || VAX630 || VAX670
#define NGEN 1
cons_init(gen), /* Generic console type; mtpr/mfpr */
#else
#define NGEN 0
#endif
-#if VAX410 || VAX43
-#define NDZCN 1
+#if VAX410 || VAX43 || VAX46 || VAX48 || VAX49
cons_init(dz), /* DZ11-like serial console on VAXstations */
-#else
-#define NDZCN 0
#endif
-#if 0 /* VAX410 || VAX43 || VAX650 || VAX630 */
+#if VAX650 || VAX630
+#if NQV
cons_init(qv), /* QVSS/QDSS bit-mapped console driver */
+#endif
+#if NQD
cons_init(qd),
#endif
+#endif
+#if NSMG
+ cons_init(smg),
+#endif
#ifdef notyet
/* We may not always use builtin console, sometimes RD */
- { rdcnprobe, rdcninit, rdcngetc, rdcnputc },
+ { hdcnprobe, hdcninit, hdcngetc, hdcnputc },
#endif
{ 0 }
};
/* Special for console storage */
#define dev_type_rw(n) int n __P((dev_t, int, int, struct proc *))
-/* plotters - open, close, write, ioctl, select */
+/* plotters - open, close, write, ioctl, select*/
#define cdev_plotter_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
(dev_type_stop((*))) nullop, 0, (dev_type_select((*))) nullop, \
(dev_type_mmap((*))) enodev }
+/* open, close, read, write, ioctl, stop, tty, select, mmap */
+#define cdev_wscons_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
+ dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
+ dev_init(c,n,tty), ttselect, dev_init(c,n,mmap), D_TTY }
cdev_decl(cn);
cdev_decl(idc);
cdev_decl(fd);
cdev_decl(gencn);
-cdev_decl(dzcn);
cdev_decl(rx);
cdev_decl(rl);
cdev_decl(ccd);
-cdev_decl(hdc);
+cdev_decl(raid);
+cdev_decl(hd);
+cdev_decl(ry);
cdev_decl(sd);
cdev_decl(st);
#define crlwrite crlrw
cdev_decl(crl);
-#if VAX8200 && 0
+#if VAX8200
#define NCRX 1
#else
#define NCRX 0
#define crxwrite crxrw
cdev_decl(crx);
-#ifdef notyet
#if VAX780
#define NCFL 1
#else
#define cflread cflrw
#define cflwrite cflrw
cdev_decl(cfl);
-#endif
#include "dz.h"
cdev_decl(dz);
#include "dmz.h"
cdev_decl(dmz);
-#include "qv.h"
cdev_decl(qv);
-
-#include "qd.h"
cdev_decl(qd);
-#ifdef IPFILTER
-#define NIPF 1
-#else
-#define NIPF 0
-#endif
-
#include "dl.h"
cdev_decl(dl);
cdev_decl(xfs_dev);
#endif
-cdev_decl(random);
-
dev_decl(filedesc,open);
+#include "wscons.h"
+cdev_decl(wscons);
+
struct cdevsw cdevsw[] =
{
cdev_cn_init(1,cn), /* 0: virtual console */
cdev_notdef(), /* 5 */
cdev_plotter_init(NVP,vp), /* 6: Versatec plotter */
cdev_swap_init(1,sw), /* 7 */
-#ifdef notyet
cdev_cnstore_init(NCFL,cfl), /* 8: 11/780 console floppy */
-#else
- cdev_notdef(), /* 8 */
-#endif
cdev_disk_init(NRA,ra), /* 9: MSCP disk interface */
cdev_plotter_init(NVA,va), /* 10: Benson-Varian plotter */
cdev_disk_init(NRK,rk), /* 11: RK06/07 */
cdev_graph_init(NPS,ps), /* 27: E/S graphics device */
cdev_lkm_init(NLKM,lkm), /* 28: loadable module driver */
cdev_ch_init(NAD,ad), /* 29: DT A/D converter */
- cdev_disk_init(NRX,rx), /* 30: RX01/02 on unibus */
+ cdev_disk_init(NRX,rx), /* 30: RX?? on MSCP */
cdev_graph_init(NIK,ik), /* 31: Ikonas frame buffer */
cdev_disk_init(NRL,rl), /* 32: RL01/02 on unibus */
cdev_log_init(1,log), /* 33: /dev/klog */
cdev_tty_init(NDHU,dhu), /* 34: DHU-11 */
cdev_cnstore_init(NCRL,crl), /* 35: Console RL02 on 8600 */
- cdev_tty_init(NDZCN,dzcn), /* 36: DZ11-like console on VAXst. */
+ cdev_notdef(), /* 36 */
cdev_tty_init(NDMZ,dmz), /* 37: DMZ32 */
cdev_tape_init(NMT,mt), /* 38: MSCP tape */
cdev_audio_init(NNP,np), /* 39: NP Intelligent Board */
cdev_graph_init(NQV,qv), /* 40: QVSS graphic display */
cdev_graph_init(NQD,qd), /* 41: QDSS graphic display */
- cdev_gen_ipf(NIPF,ipl), /* 42: ip filtering */
+ cdev_gen_ipf(NIPF,ipl), /* 42: Packet filter */
cdev_ingres_init(NII,ii), /* 43: Ingres device */
cdev_notdef(), /* 44 was Datakit */
cdev_notdef(), /* 45 was Datakit */
cdev_notdef(), /* 47 */
cdev_notdef(), /* 48 */
cdev_notdef(), /* 49 */
-#ifdef XFS
- cdev_xfs_init(NXFS,xfs_dev), /* 50: xfs communication device */
-#else
- cdev_notdef(), /* 50 */
-#endif
+ cdev_ksyms_init(NKSYMS,ksyms), /* 50: Kernel symbols device */
cdev_cnstore_init(NCRX,crx), /* 51: Console RX50 at 8200 */
cdev_notdef(), /* 52: was: KDB50/RA?? */
cdev_fd_init(1,filedesc), /* 53: file descriptor pseudo-device */
cdev_disk_init(NVND,vnd), /* 55: vnode disk driver */
cdev_bpftun_init(NBPFILTER,bpf),/* 56: berkeley packet filter */
cdev_bpftun_init(NTUN,tun), /* 57: tunnel filter */
- cdev_disk_init(NHDC,hdc), /* 58: HDC9224/RD?? */
+ cdev_disk_init(NHD,hd), /* 58: HDC9224/RD?? */
cdev_disk_init(NSD,sd), /* 59: SCSI disk */
cdev_tape_init(NST,st), /* 60: SCSI tape */
cdev_disk_init(NCD,cd), /* 61: SCSI CD-ROM */
- cdev_notdef(), /* 62: was: memory disk driver */
+ cdev_notdef(), /* 62: was: memory disk driver */
cdev_ch_init(NCH,ch), /* 63: SCSI autochanger */
cdev_scanner_init(NSS,ss), /* 64: SCSI scanner */
cdev_uk_init(NUK,uk), /* 65: SCSI unknown */
- cdev_random_init(1,random), /* 66: random data source */
- cdev_tty_init(NDL,dl), /* 67; DL11 */
+ cdev_tty_init(NDL,dl), /* 66: DL11 */
+ cdev_random_init(1,random), /* 67: random data source */
+ cdev_wscons_init(NWSCONS, wscons), /* 68: workstation console */
+ cdev_disk_init(NRY,ry), /* 71: VS floppy */
+ cdev_notdef(), /* 72: was: SCSI bus */
+ cdev_disk_init(NRAID,raid), /* 73: RAIDframe disk driver */
+#ifdef XFS
+ cdev_xfs_init(NXFS,xfs_dev), /* 74: xfs communication device */
+#else
+ cdev_notdef(), /* 74 */
+#endif
+
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
21, /* 60 */
22, /* 61 */
23, /* 62 */
+ NODEV, /* 63 */
+ NODEV, /* 64 */
+ NODEV, /* 65 */
+ NODEV, /* 66 */
+ NODEV, /* 67 */
+ NODEV, /* 68 */
+ NODEV, /* 69 */
+ NODEV, /* 70 */
+ NODEV, /* 71 */
+ NODEV, /* 72 */
+ 25, /* 73 */
+ NODEV, /* 74 */
};
-int
+dev_t
chrtoblk(dev)
dev_t dev;
{
+ int blkmaj;
+
if (major(dev) >= nchrdev ||
major(dev) > sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]))
return (NODEV);
return (makedev(blkmaj, minor(dev)));
}
+/*
+ * Convert a character device number to a block device number.
+ */
+dev_t
+blktochr(dev)
+ dev_t dev;
+{
+ int blkmaj = major(dev);
+ int i;
+
+ if (blkmaj >= nblkdev)
+ return (NODEV);
+ for (i = 0; i < sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]); i++)
+ if (blkmaj == chrtoblktbl[i])
+ return (makedev(i, minor(dev)));
+ return (NODEV);
+}
+
/*
* Returns true if dev is /dev/mem or /dev/kmem.
*/
iskmemdev(dev)
dev_t dev;
{
-
return (major(dev) == 3 && minor(dev) < 2);
}
return (major(dev) == 3 && minor(dev) == 12);
}
-/*
- * Convert a character device number to a block device number.
- */
-dev_t
-blktochr(dev)
- dev_t dev;
-{
- int blkmaj = major(dev);
- int i;
-
- if (blkmaj >= nblkdev)
- return (NODEV);
- for (i = 0; i < sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]); i++)
- if (blkmaj == chrtoblktbl[i])
- return (makedev(i, minor(dev)));
- return (NODEV);
-}
-/* $OpenBSD: crl.c,v 1.3 1997/05/29 00:05:13 niklas Exp $ */
-/* $NetBSD: crl.c,v 1.5 1996/10/13 03:35:35 christos Exp $ */
+/* $OpenBSD: crl.c,v 1.4 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: crl.c,v 1.6 2000/01/24 02:40:33 matt Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* All rights reserved.
int crl_ds; /* saved drive status */
} crlstat;
-void crlintr __P((int));
+void crlintr __P((void *));
void crlattach __P((void));
static void crlstart __P((void));
void
crlattach()
{
- extern struct ivec_dsp idsptch;
-
- bcopy(&idsptch, &crl_intr, sizeof(struct ivec_dsp));
- scb->scb_csrint = &crl_intr;
+ crl_intr = idsptch;
crl_intr.hoppaddr = crlintr;
+ scb->scb_csrint = &crl_intr;
}
/*ARGSUSED*/
mtpr(bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE, PR_STXCS);
}
#ifdef lint
- crlintr();
+ crlintr(NULL);
#endif
}
void
crlintr(arg)
- int arg;
+ void *arg;
{
register struct buf *bp;
int i;
-/* $OpenBSD: crl.h,v 1.2 1997/05/29 00:05:14 niklas Exp $ */
-/* $NetBSD: crl.h,v 1.1 1996/03/08 12:32:53 ragge Exp $ */
+/* $OpenBSD: crl.h,v 1.3 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: crl.h,v 1.2 1999/04/12 20:57:52 pk Exp $ */
/*
* @(#)crl.h 7.1 (Berkeley) 6/5/86
*/
* *
* If the Regents of the University of California or its *
* licensees modify the software in a manner creating *
- * diriviative copyright rights, appropriate copyright *
- * legends may be placed on the drivative work in addition *
+ * derivative copyright rights, appropriate copyright *
+ * legends may be placed on the derivative work in addition *
* to that set forth above. *
****************************************************************/
--- /dev/null
+/* $OpenBSD: crx.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: crx.c,v 1.4 2000/01/24 02:40:33 matt Exp $ */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)rx50.c 7.5 (Berkeley) 12/16/90
+ */
+
+/*
+ * Routines to handle the console RX50.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+
+#include <machine/ka820.h>
+#include <vax/vax/crx.h>
+
+extern struct rx50device *rx50device_ptr;
+#define rxaddr rx50device_ptr
+extern struct ka820port *ka820port_ptr;
+
+#define rx50unit(dev) minor(dev)
+
+cdev_decl(crx);
+
+struct rx50state {
+ short rs_flags; /* see below */
+ short rs_drive; /* current drive number */
+ u_int rs_blkno; /* current block number */
+} rx50state;
+
+/* flags */
+#define RS_0OPEN 0x01 /* drive 0 open -- must be first */
+#define RS_1OPEN 0x02 /* drive 1 open -- must be second */
+#define RS_BUSY 0x04 /* operation in progress */
+#define RS_WANT 0x08 /* wakeup when done */
+#define RS_DONE 0x20 /* I/O operation done */
+#define RS_ERROR 0x40 /* error bit set at interrupt */
+
+#if 0
+#define CRXDEBUG 1
+#endif
+
+/*
+ * Open a console RX50.
+ */
+/*ARGSUSED*/
+int
+crxopen(dev, flags, fmt, p)
+ dev_t dev;
+ int flags, fmt;
+ struct proc *p;
+{
+ int unit;
+
+#if CRXDEBUG
+ printf("crxopen(csa%d)\n", minor(dev));
+#endif
+ if ((unit = rx50unit(dev)) >= 2)
+ return (ENXIO);
+
+ /* enforce exclusive access */
+ if (rx50state.rs_flags & (1 << unit))
+ return (EBUSY);
+ rx50state.rs_flags |= 1 << unit;
+
+ return (0);
+}
+
+/*
+ * Close a console RX50.
+ */
+/*ARGSUSED*/
+int
+crxclose(dev, flags, fmt, p)
+ dev_t dev;
+ int flags, fmt;
+ struct proc *p;
+{
+#if CRXDEBUG
+ printf("crxclose(csa%d)\n", minor(dev));
+#endif
+
+ rx50state.rs_flags &= ~(1 << dev); /* atomic */
+ return 0;
+}
+
+/*
+ * Perform a read (uio->uio_rw==UIO_READ) or write (uio->uio_rw==UIO_WRITE).
+ */
+int crxrw __P((dev_t, struct uio *, int));
+int
+crxrw(dev, uio, flags)
+ dev_t dev;
+ register struct uio *uio;
+ int flags;
+{
+ register struct rx50state *rs;
+ register char *cp;
+ register int error, i, t;
+ char secbuf[512];
+ static char driveselect[2] = { RXCMD_DRIVE0, RXCMD_DRIVE1 };
+
+#if CRXDEBUG
+ printf("crxrw(csa%d): %s\n",
+ minor(dev), uio->uio_rw==UIO_READ?"read":"write");
+ printf("crxrw: ka820port = %x\n", ka820port_ptr->csr);
+#endif
+ /* enforce whole-sector I/O */
+ if ((uio->uio_offset & 511) || (uio->uio_resid & 511))
+ return (EINVAL);
+
+ rs = &rx50state;
+
+ /* lock out others */
+ i = spl4();
+ while (rs->rs_flags & RS_BUSY) {
+ rs->rs_flags |= RS_WANT;
+ sleep((caddr_t) &rx50state, PRIBIO);
+ }
+ rs->rs_flags |= RS_BUSY;
+ rs->rs_drive = rx50unit(dev);
+ splx(i);
+
+ rxaddr = rx50device_ptr;
+ error = 0;
+
+ while (uio->uio_resid) {
+ rs->rs_blkno = uio->uio_offset >> 9;
+ if (rs->rs_blkno >= RX50MAXSEC) {
+ if (rs->rs_blkno > RX50MAXSEC)
+ error = EINVAL;
+ else if (uio->uio_rw == UIO_WRITE)
+ error = ENOSPC;
+ /* else ``eof'' */
+ break;
+ }
+ rs->rs_flags &= ~(RS_ERROR | RS_DONE);
+ if (uio->uio_rw == UIO_WRITE) {
+ /* copy the data to the RX50 silo */
+ error = uiomove(secbuf, 512, uio);
+ if (error)
+ break;
+ i = rxaddr->rxrda;
+ for (cp = secbuf, i = 512; --i >= 0;)
+ rxaddr->rxfdb = *cp++;
+ i = RXCMD_WRITE;
+ } else
+ i = RXCMD_READ;
+ rxaddr->rxcmd = i | driveselect[rs->rs_drive];
+ i = rs->rs_blkno - ((t = rs->rs_blkno / RX50SEC) * RX50SEC);
+ rxaddr->rxtrk = t == 79 ? 0 : t + 1;
+#ifdef notdef
+ rxaddr->rxsec = "\1\3\5\7\11\1\3\5\7"[(2*t + i) % 5] + (i > 4);
+#else
+ rxaddr->rxsec = RX50SKEW(i, t);
+#endif
+#if CRXDEBUG
+ printf("crx: going off\n");
+ printf("crxrw: ka820port = %x\n", ka820port_ptr->csr);
+#endif
+ rxaddr->rxgo = 0; /* start it up */
+ ka820port_ptr->csr |= KA820PORT_RXIRQ;
+ i = spl4();
+ while ((rs->rs_flags & RS_DONE) == 0) {
+#if CRXDEBUG
+ printf("crx: sleeping on I/O\n");
+ printf("crxopen: ka820port = %x\n", ka820port_ptr->csr);
+#endif
+ sleep((caddr_t) &rs->rs_blkno, PRIBIO);
+ }
+ splx(i);
+ if (rs->rs_flags & RS_ERROR) {
+ error = EIO;
+ break;
+ }
+ if (uio->uio_rw == UIO_READ) {
+ /* copy the data out of the silo */
+ i = rxaddr->rxrda;
+ for (cp = secbuf, i = 512; --i >= 0;)
+ *cp++ = rxaddr->rxedb;
+ error = uiomove(secbuf, 512, uio);
+ if (error)
+ break;
+ }
+ }
+
+ /* let others in */
+#if CRXDEBUG
+ printf("crx: let others in\n");
+#endif
+ rs->rs_flags &= ~RS_BUSY;
+ if (rs->rs_flags & RS_WANT)
+ wakeup((caddr_t) rs);
+
+ return (error);
+}
+
+void
+crxintr(arg)
+ void *arg;
+{
+ register struct rx50state *rs = &rx50state;
+
+ /* ignore spurious interrupts */
+ if ((rxaddr->rxcmd & RXCMD_DONE) == 0)
+ return;
+ if ((rs->rs_flags & RS_BUSY) == 0) {
+ printf("stray rx50 interrupt ignored (rs_flags: 0x%x, rxcmd: 0x%x)\n",
+ rs->rs_flags, rxaddr->rxcmd);
+ return;
+ }
+ if (rxaddr->rxcmd & RXCMD_ERROR) {
+ printf(
+ "csa%d: hard error sn%d: cmd=%x trk=%x sec=%x csc=%x ict=%x ext=%x\n",
+ rs->rs_drive + 1, rs->rs_blkno,
+ rxaddr->rxcmd, rxaddr->rxtrk, rxaddr->rxsec,
+ rxaddr->rxcsc, rxaddr->rxict, rxaddr->rxext);
+ rxaddr->rxcmd = RXCMD_RESET;
+ rxaddr->rxgo = 0;
+ rs->rs_flags |= RS_ERROR;
+ }
+ rs->rs_flags |= RS_DONE;
+ wakeup((caddr_t) &rs->rs_blkno);
+}
--- /dev/null
+/* $OpenBSD: crx.h,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: crx.h,v 1.2 1999/01/19 21:04:48 ragge Exp $ */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)rx50reg.h 7.2 (Berkeley) 6/28/90
+ */
+
+/*
+ * RX50 registers.
+ */
+
+/*
+ * The names below do not quite match the DEC documentation simply because
+ * the names in the documentation are so bad.
+ */
+struct rx50device {
+ u_short rxid; /* identification */
+ u_short reserved;
+ u_short rxcmd; /* command function reg */
+ u_short rxtrk; /* track */
+ u_short rxsec; /* sector */
+ u_short rxcsc; /* current sector */
+ u_short rxict; /* incorrect track (???) */
+ u_short rxext; /* extend command register */
+ u_short rxedb; /* empty data buffer (read) */
+ u_short rxrda; /* reset data address */
+ volatile u_short rxgo; /* read to start current cmd */
+ u_short rxfdb; /* fill data buffer (write) */
+};
+
+#define RX50SEC 10 /* sectors per track */
+#define RX50MAXSEC 800 /* 10 sectors times 80 tracks */
+
+/* Interrupt vector */
+#define SCB_RX50 0xf0
+
+/*
+ * Do the sector skew given the sector and track
+ * number (it depends on both!).
+ */
+/* (((((s) / 5) + 2 * ((s) + (t))) % 10) + 1) */
+#define RX50SKEW(s, t) (((s) / 5) + "\1\3\5\7\11\1\3\5\7"[((s) + (t)) % 5])
+
+/*
+ * Values in the command function register.
+ */
+#define RXCMD_ERROR 0x80 /* error bit (composite?) */
+#define RXCMD_READ 0x40 /* read command */
+#define RXCMD_WRITE 0x70 /* write command */
+#define RXCMD_RESET 0x20 /* reset command */
+#define RXCMD_DONE 0x08 /* operation done (status) */
+#define RXCMD_DRIVE0 0x00 /* select drive 0 (csa1) */
+#define RXCMD_DRIVE1 0x02 /* select drive 1 (csa2) */
-/* $OpenBSD: ctu.c,v 1.3 1997/05/29 00:05:14 niklas Exp $ */
-/* $NetBSD: ctu.c,v 1.5 1996/10/13 03:35:36 christos Exp $ */
+/* $OpenBSD: ctu.c,v 1.4 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: ctu.c,v 1.10 2000/03/23 06:46:44 thorpej Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/buf.h>
#include <sys/fcntl.h>
SC_RESTART,
};
-volatile struct tu_softc {
+struct tu_softc {
enum tu_state sc_state;
int sc_error;
char sc_rsp[15]; /* Should be struct rsb; but don't work */
int sc_bbytes; /* Number of xfer'd bytes this block */
int sc_op; /* Read/write */
int sc_xmtok; /* set if OK to xmit */
- struct buf sc_q; /* Current buffer */
+ struct buf_queue sc_q; /* pending I/O requests */
} tu_sc;
struct ivec_dsp tu_recv, tu_xmit;
-void ctutintr __P((int));
-void cturintr __P((int));
+void ctutintr __P((void *));
+void cturintr __P((void *));
void ctuattach __P((void));
void ctustart __P((struct buf *));
void ctuwatch __P((void *));
int ctuioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
int ctudump __P((dev_t, daddr_t, caddr_t, size_t));
+static struct callout ctu_watch_ch = CALLOUT_INITIALIZER;
void
ctuattach()
{
- extern struct ivec_dsp idsptch;
+ BUFQ_INIT(&tu_sc.sc_q);
- bcopy(&idsptch, &tu_recv, sizeof(struct ivec_dsp));
- bcopy(&idsptch, &tu_xmit, sizeof(struct ivec_dsp));
- scb->scb_csrint = (void *)&tu_recv;
- scb->scb_cstint = (void *)&tu_xmit;
+ tu_recv = idsptch;
tu_recv.hoppaddr = cturintr;
+ scb->scb_csrint = (void *)&tu_recv;
+
+ tu_xmit = idsptch;
tu_xmit.hoppaddr = ctutintr;
+ scb->scb_cstint = (void *)&tu_xmit;
}
int
tu_sc.sc_error = 0;
mtpr(0100, PR_CSRS); /* Enable receive interrupt */
- timeout(ctuwatch, 0, 100); /* Check once/second */
+ callout_reset(&ctu_watch_ch, hz, ctuwatch, NULL);
tu_sc.sc_state = SC_INIT;
mtpr(0, PR_CSRS);
mtpr(0, PR_CSTS);
tu_sc.sc_state = SC_UNUSED;
- untimeout(ctuwatch, 0);
+ callout_stop(&ctu_watch_ch);
return 0;
}
#endif
if (bp->b_blkno >= 512) {
- iodone(bp);
+ biodone(bp);
return;
}
- bp->b_cylinder = bp->b_blkno;
+ bp->b_rawblkno = bp->b_blkno;
s = splimp();
- disksort((struct buf *)&tu_sc.sc_q, bp); /* Why not use disksort? */
+ disksort_blkno(&tu_sc.sc_q, bp); /* Why not use disksort? */
if (tu_sc.sc_state == SC_READY)
ctustart(bp);
splx(s);
tu_sc.sc_state = SC_SEND_CMD;
if (tu_sc.sc_xmtok) {
tu_sc.sc_xmtok = 0;
- ctutintr(0);
+ ctutintr(NULL);
}
}
void
cturintr(arg)
- int arg;
+ void *arg;
{
int status = mfpr(PR_CSRD);
struct buf *bp;
- bp = tu_sc.sc_q.b_actf;
+ bp = BUFQ_FIRST(&tu_sc.sc_q);
switch (tu_sc.sc_state) {
case SC_UNUSED:
#ifdef TUDEBUG
printf("Xfer ok\n");
#endif
- tu_sc.sc_q.b_actf = bp->b_actf;
- iodone(bp);
+ BUFQ_REMOVE(&tu_sc.sc_q, bp);
+ biodone(bp);
tu_sc.sc_xmtok = 1;
tu_sc.sc_state = SC_READY;
- if (tu_sc.sc_q.b_actf)
- ctustart(tu_sc.sc_q.b_actf);
+ if (BUFQ_FIRST(&tu_sc.sc_q) != NULL)
+ ctustart(BUFQ_FIRST(&tu_sc.sc_q));
}
break;
}
if (status != 020)
printf("SC_GET_WCONT: status %o\n", status);
else
- ctutintr(0);
+ ctutintr(NULL);
tu_sc.sc_xmtok = 0;
break;
case SC_RESTART:
- ctustart(tu_sc.sc_q.b_actf);
+ ctustart(BUFQ_FIRST(&tu_sc.sc_q));
break;
default:
void
ctutintr(arg)
- int arg;
+ void *arg;
{
int c;
void *arg;
{
- timeout(ctuwatch, 0, 1000);
+ callout_reset(&ctu_watch_ch, hz, ctuwatch, NULL);
if (tu_sc.sc_state == SC_GET_RESP && tu_sc.sc_tpblk != 0 &&
tu_sc.sc_tpblk == oldtp && (tu_sc.sc_tpblk % 128 != 0)) {
printf("tu0: lost recv interrupt\n");
- ctustart(tu_sc.sc_q.b_actf);
+ ctustart(BUFQ_FIRST(&tu_sc.sc_q));
return;
}
if (tu_sc.sc_state == SC_RESTART)
-/* $OpenBSD: db_disasm.c,v 1.7 1997/05/29 00:05:15 niklas Exp $ */
-/* $NetBSD: db_disasm.c,v 1.9 1996/10/13 03:35:38 christos Exp $ */
+/* $OpenBSD: db_disasm.c,v 1.8 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: db_disasm.c,v 1.10 1998/04/13 12:10:27 ragge Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/reboot.h>
+#include <sys/systm.h>
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
+#include <ddb/db_interface.h>
+#include <ddb/db_output.h>
#include <vax/vax/db_disasm.h>
inst_buffer *ib;
char *s;
{
- while (*ib->curp++ = *s++);
+ while ((*ib->curp++ = *s++));
*--ib->curp = '\0';
}
-/* $OpenBSD: db_machdep.c,v 1.7 1997/10/06 15:12:58 niklas Exp $ */
-/* $NetBSD: db_machdep.c,v 1.8 1996/10/13 03:35:39 christos Exp $ */
+/* $OpenBSD: db_machdep.c,v 1.8 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: db_machdep.c,v 1.17 1999/06/20 00:58:23 ragge Exp $ */
/*
* Mach Operating System
* 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
+ * 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.
*
* rights to redistribute these changes.
*
* db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
+ *
+ * VAX enhancements by cmcmanis@mcmanis.com no rights reserved :-)
+ *
*/
/*
*/
#include <sys/param.h>
#include <sys/proc.h>
+#include <sys/user.h>
#include <sys/reboot.h>
#include <sys/systm.h> /* just for boothowto --eichin */
#include <vm/vm.h>
+#include <dev/cons.h>
+
#include <machine/db_machdep.h>
#include <machine/trap.h>
#include <machine/frame.h>
+#include <machine/pcb.h>
#include <machine/cpu.h>
#include <machine/../vax/gencons.h>
int db_active = 0;
+extern int qdpolling;
+static int splsave; /* IPL before entering debugger */
+
+/*
+ * VAX Call frame on the stack, this from
+ * "Computer Programming and Architecture, The VAX-11"
+ * Henry Levy & Richard Eckhouse Jr.
+ * ISBN 0-932376-07-X
+ */
+typedef struct __vax_frame {
+ u_int vax_cond; /* condition handler */
+ u_int vax_psw:16; /* 16 bit processor status word */
+ u_int vax_regs:12; /* Register save mask. */
+ u_int vax_zero:1; /* Always zero */
+ u_int vax_calls:1; /* True if CALLS, false if CALLG */
+ u_int vax_spa:2; /* Stack pointer alignment */
+ u_int *vax_ap; /* argument pointer */
+ struct __vax_frame *vax_fp; /* frame pointer of previous frame */
+ u_int vax_pc; /* program counter */
+ u_int vax_args[1]; /* 0 or more arguments */
+} VAX_CALLFRAME;
+
/*
* DDB is called by either <ESC> - D on keyboard, via a TRACE or
* BPT trap or from kernel, normally as a result of a panic.
case T_TRCTRAP: /* single_step */
break;
+ /* XXX todo: should be migrated to use VAX_CALLFRAME at some point */
case T_KDBTRAP:
if (panicstr) {
struct callsframe *pf, *df;
ddb_regs.pc = pf->ca_pc;
ddb_regs.ap = pf->ca_ap;
ddb_regs.sp = (unsigned)pf;
- ddb_regs.psl = frame->psl & ~0xffe0;
- ddb_regs.psl = pf->ca_maskpsw & 0xffe0;
+ ddb_regs.psl = frame->psl & ~0x1fffe0;
+ ddb_regs.psl |= pf->ca_maskpsw & 0xffe0;
+ ddb_regs.psl |= (splsave << 16);
}
break;
/* XXX Should switch to interrupt stack here, if needed. */
- s = splddb();
- mtpr(0, PR_RXCS);
- mtpr(0, PR_TXCS);
+ s = splimp();
db_active++;
+ cnpollc(TRUE);
db_trap(frame->trap, frame->code);
+ cnpollc(FALSE);
db_active--;
- mtpr(GC_RIE, PR_RXCS);
- mtpr(GC_TIE, PR_TXCS);
splx(s);
if (!panicstr)
void
db_read_bytes(addr, size, data)
vm_offset_t addr;
- size_t size;
- char *data;
+ size_t size;
+ char *data;
{
- char *src;
- size_t i;
-
- src = (char *)addr;
- for (i = 0; i < size; i++)
- *data++ = *src++;
+ bcopy((caddr_t)addr, data, size);
}
/*
void
db_write_bytes(addr, size, data)
vm_offset_t addr;
- size_t size;
- char *data;
+ size_t size;
+ char *data;
{
- char *dst;
- size_t i;
-
- dst = (char *)addr;
- for (i = 0; i < size; i++)
- *dst++ = *data++;
+ memcpy((caddr_t)addr, data, size);
}
void
Debugger()
{
- int s = splx(0xe); /* Is this good? We must lower anyway... */
+ splsave = splx(0xe);
mtpr(0xf, PR_SIRR); /* beg for debugger */
- splx(s);
+ splx(splsave);
}
/*
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+#define IN_USERLAND(x) (((u_int)(x) & 0x80000000) == 0)
+
+/*
+ * Dump a stack traceback. Takes two arguments:
+ * fp - CALL FRAME pointer
+ * stackbase - Lowest stack value
+ */
+static void
+db_dump_stack(VAX_CALLFRAME *fp, u_int stackbase) {
+ u_int nargs, arg_base, regs;
+ VAX_CALLFRAME *tmp_frame;
+ db_expr_t diff;
+ db_sym_t sym;
+ char *symname;
+
+ db_printf("Stack traceback : \n");
+ if (IN_USERLAND(fp)) {
+ db_printf(" Process is executing in user space.\n");
+ return;
+ }
+
+ while (((u_int)(fp->vax_fp) > stackbase) &&
+ ((u_int)(fp->vax_fp) < (stackbase + USPACE))) {
+
+ diff = INT_MAX;
+ symname = NULL;
+ sym = db_search_symbol(fp->vax_pc, DB_STGY_ANY, &diff);
+ db_symbol_values(sym, &symname, 0);
+ db_printf("%s+0x%lx(", symname, diff);
+
+ /*
+ * Figure out the arguments by using a bit of subtlety.
+ * As the argument pointer may have been used as a temporary
+ * by the callee ... recreate what it would have pointed to
+ * as follows:
+ * The vax_regs value has a 12 bit bitmask of the registers
+ * that were saved on the stack.
+ * Store that in 'regs' and then for every bit that is
+ * on (indicates the register contents are on the stack)
+ * increment the argument base (arg_base) by one.
+ * When that is done, args[arg_base] points to the longword
+ * that identifies the number of arguments.
+ * arg_base+1 - arg_base+n are the argument pointers/contents.
+ */
+
+ /* First get the frame that called this function ... */
+ tmp_frame = fp->vax_fp;
+
+ /* Isolate the saved register bits, and count them */
+ regs = tmp_frame->vax_regs;
+ for (arg_base = 0; regs != 0; regs >>= 1) {
+ if (regs & 1)
+ arg_base++;
+ }
+
+ /* number of arguments is then pointed to by vax_args[arg_base] */
+ nargs = tmp_frame->vax_args[arg_base];
+ if (nargs) {
+ nargs--; /* reduce by one for formatting niceties */
+ arg_base++; /* skip past the actual number of arguments */
+ while (nargs--)
+ db_printf("0x%x,", tmp_frame->vax_args[arg_base++]);
+
+ /* now print out the last arg with closing brace and \n */
+ db_printf("0x%x)\n", tmp_frame->vax_args[++arg_base]);
+ } else
+ db_printf("void)\n");
+ /* move to the next frame */
+ fp = fp->vax_fp;
+ }
+}
+
+/*
+ * Implement the trace command which has the form:
+ *
+ * trace <-- Trace panic (same as before)
+ * trace 0x88888 <-- Trace process whose address is 888888
+ * trace/t <-- Trace current process (0 if no current proc)
+ * trace/t 0tnn <-- Trace process nn (0t for decimal)
+ */
void
db_stack_trace_cmd(addr, have_addr, count, modif)
- db_expr_t addr;
- boolean_t have_addr;
- db_expr_t count;
- char *modif;
+ db_expr_t addr; /* Address parameter */
+ boolean_t have_addr; /* True if addr is valid */
+ db_expr_t count; /* Optional count */
+ char *modif; /* pointer to flag modifier 't' */
{
- printf("db_stack_trace_cmd - addr %x, have_addr %x, count %x, modif %x\n",addr, have_addr, count, (int)modif);
+ extern vaddr_t proc0paddr;
+ struct proc *p = curproc;
+ struct user *uarea;
+ int trace_proc;
+ pid_t curpid;
+ char *s;
+
+ /* Check to see if we're tracing a process */
+ trace_proc = 0;
+ s = modif;
+ while (!trace_proc && *s) {
+ if (*s++ == 't')
+ trace_proc++; /* why yes we are */
+ }
+
+ /* Trace a panic */
+ if (! trace_proc) {
+ if (! panicstr) {
+ db_printf("Not a panic, use trace/t to trace a process.\n");
+ return;
+ }
+ db_printf("panic: %s\n", panicstr);
+ /* xxx ? where did we panic and whose stack are we using? */
+ db_dump_stack((VAX_CALLFRAME *)(ddb_regs.sp), ddb_regs.ap);
+ return;
+ }
+
+ /*
+ * If user typed an address its either a PID, or a Frame
+ * if no address then either current proc or panic
+ */
+ if (have_addr) {
+ if (trace_proc) {
+ p = pfind((int)addr);
+ /* Try to be helpful by looking at it as if it were decimal */
+ if (p == NULL) {
+ u_int tpid = 0;
+ u_int foo = addr;
+
+ while (foo != 0) {
+ int digit = (foo >> 28) & 0xf;
+ if (digit > 9) {
+ db_printf(" No such process.\n");
+ return;
+ }
+ tpid = tpid * 10 + digit;
+ foo = foo << 4;
+ }
+ p = pfind(tpid);
+ if (p == NULL) {
+ db_printf(" No such process.\n");
+ return;
+ }
+ }
+ } else {
+ p = (struct proc *)(addr);
+ if (pfind(p->p_pid) != p) {
+ db_printf(" This address does not point to a valid process.\n");
+ return;
+ }
+ }
+ } else {
+ if (trace_proc) {
+ p = curproc;
+ if (p == NULL) {
+ db_printf("trace: no current process! (ignored)\n");
+ return;
+ }
+ } else {
+ if (! panicstr) {
+ db_printf("Not a panic, no active process, ignored.\n");
+ return;
+ }
+ }
+ }
+ if (p == NULL) {
+ uarea = (struct user *)proc0paddr;
+ curpid = 0;
+ } else {
+ uarea = p->p_addr;
+ curpid = p->p_pid;
+ }
+ db_printf("Process %d\n", curpid);
+ db_printf(" PCB contents:\n");
+ db_printf(" KSP = 0x%x\n", (unsigned int)(uarea->u_pcb.KSP));
+ db_printf(" ESP = 0x%x\n", (unsigned int)(uarea->u_pcb.ESP));
+ db_printf(" SSP = 0x%x\n", (unsigned int)(uarea->u_pcb.SSP));
+ db_printf(" USP = 0x%x\n", (unsigned int)(uarea->u_pcb.USP));
+ db_printf(" R[00] = 0x%08x R[06] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[0]), (unsigned int)(uarea->u_pcb.R[6]));
+ db_printf(" R[01] = 0x%08x R[07] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[1]), (unsigned int)(uarea->u_pcb.R[7]));
+ db_printf(" R[02] = 0x%08x R[08] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[2]), (unsigned int)(uarea->u_pcb.R[8]));
+ db_printf(" R[03] = 0x%08x R[09] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[3]), (unsigned int)(uarea->u_pcb.R[9]));
+ db_printf(" R[04] = 0x%08x R[10] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[4]), (unsigned int)(uarea->u_pcb.R[10]));
+ db_printf(" R[05] = 0x%08x R[11] = 0x%08x\n",
+ (unsigned int)(uarea->u_pcb.R[5]), (unsigned int)(uarea->u_pcb.R[11]));
+ db_printf(" AP = 0x%x\n", (unsigned int)(uarea->u_pcb.AP));
+ db_printf(" FP = 0x%x\n", (unsigned int)(uarea->u_pcb.FP));
+ db_printf(" PC = 0x%x\n", (unsigned int)(uarea->u_pcb.PC));
+ db_printf(" PSL = 0x%x\n", (unsigned int)(uarea->u_pcb.PSL));
+ db_printf(" Trap frame pointer: 0x%x\n",
+ (unsigned int)(uarea->u_pcb.framep));
+ db_dump_stack((VAX_CALLFRAME *)(uarea->u_pcb.FP), (u_int) uarea->u_pcb.KSP);
+ return;
+#if 0
+ while (((u_int)(cur_frame->vax_fp) > stackbase) &&
+ ((u_int)(cur_frame->vax_fp) < (stackbase + USPACE))) {
+ u_int nargs;
+ VAX_CALLFRAME *tmp_frame;
+
+ diff = INT_MAX;
+ symname = NULL;
+ sym = db_search_symbol(cur_frame->vax_pc, DB_STGY_ANY, &diff);
+ db_symbol_values(sym, &symname, 0);
+ db_printf("%s+0x%lx(", symname, diff);
+
+ /*
+ * Figure out the arguments by using a bit of subterfuge
+ * since the argument pointer may have been used as a temporary
+ * by the callee ... recreate what it would have pointed to
+ * as follows:
+ * The vax_regs value has a 12 bit bitmask of the registers
+ * that were saved on the stack.
+ * Store that in 'regs' and then for every bit that is
+ * on (indicates the register contents are on the stack)
+ * increment the argument base (arg_base) by one.
+ * When that is done, args[arg_base] points to the longword
+ * that identifies the number of arguments.
+ * arg_base+1 - arg_base+n are the argument pointers/contents.
+ */
+
+ /* First get the frame that called this function ... */
+ tmp_frame = cur_frame->vax_fp;
+
+ /* Isolate the saved register bits, and count them */
+ regs = tmp_frame->vax_regs;
+ for (arg_base = 0; regs != 0; regs >>= 1) {
+ if (regs & 1)
+ arg_base++;
+ }
+
+ /* number of arguments is then pointed to by vax_args[arg_base] */
+ nargs = tmp_frame->vax_args[arg_base];
+ if (nargs) {
+ nargs--; /* reduce by one for formatting niceties */
+ arg_base++; /* skip past the actual number of arguments */
+ while (nargs--)
+ db_printf("0x%x,", tmp_frame->vax_args[arg_base++]);
+
+ /* now print out the last arg with closing brace and \n */
+ db_printf("0x%x)\n", tmp_frame->vax_args[++arg_base]);
+ } else
+ db_printf("void)\n");
+ /* move to the next frame */
+ cur_frame = cur_frame->vax_fp;
+ }
+
+ /*
+ * DEAD CODE, previous panic tracing code.
+ */
+ if (! have_addr) {
+ printf("Trace default\n");
+ if (panicstr) {
+ cf = (int *)ddb_regs.sp;
+ } else {
+ printf("Don't know what to do without panic\n");
+ return;
+ }
+ if (p)
+ paddr = (u_int)p->p_addr;
+ else
+ paddr = proc0paddr;
+
+ stackbase = (ddb_regs.psl & PSL_IS ? istack : paddr);
+ }
+#endif
}
static int ddbescape = 0;
ddbescape = 0;
return 0;
}
+
-/* $OpenBSD: disksubr.c,v 1.11 1999/01/08 04:29:10 millert Exp $ */
-/* $NetBSD: disksubr.c,v 1.13 1997/07/06 22:38:26 ragge Exp $ */
+/* $OpenBSD: disksubr.c,v 1.12 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: disksubr.c,v 1.21 1999/06/30 18:48:06 ragge Exp $ */
/*
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
#include <sys/disklabel.h>
#include <sys/syslog.h>
#include <sys/proc.h>
+#include <sys/user.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/macros.h>
#include <machine/pte.h>
#include <machine/pcb.h>
+#include <machine/cpu.h>
-#include <arch/vax/mscp/mscp.h> /* For disk encoding scheme */
-
-#define b_cylin b_resid
+#include <vax/mscp/mscp.h> /* For disk encoding scheme */
/*
* Determine the size of the transfer, and make sure it is
struct cpu_disklabel *osdep;
int wlabel;
{
-#define blockpersec(count, lp) ((count) * (((lp)->d_secsize) / DEV_BSIZE))
struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
- int labelsect = blockpersec(lp->d_partitions[2].p_offset, lp) +
- LABELSECTOR;
- int sz = howmany(bp->b_bcount, DEV_BSIZE);
+ int labelsect = lp->d_partitions[2].p_offset;
+ int maxsz = p->p_size,
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
/* avoid division by zero */
if (lp->d_secpercyl == 0) {
}
/* overwriting disk label ? */
- if (bp->b_blkno + p->p_offset <= labelsect &&
-#if LABELSECTOR != 0
- bp->b_blkno + p->p_offset + sz > labelsect &&
-#endif
+ if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
(bp->b_flags & B_READ) == 0 && wlabel == 0) {
bp->b_error = EROFS;
goto bad;
}
/* beyond partition? */
- if (bp->b_blkno + sz > blockpersec(p->p_size, lp)) {
- sz = blockpersec(p->p_size, lp) - bp->b_blkno;
- if (sz == 0) {
- /* if exactly at end of disk, return an EOF */
+ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
+ /* if exactly at end of disk, return an EOF */
+ if (bp->b_blkno == maxsz) {
bp->b_resid = bp->b_bcount;
return(0);
}
- if (sz < 0) {
+ /* or truncate if part of it fits */
+ sz = maxsz - bp->b_blkno;
+ if (sz <= 0) {
bp->b_error = EINVAL;
goto bad;
}
- /* or truncate if part of it fits */
bp->b_bcount = sz << DEV_BSHIFT;
}
/* calculate cylinder for disksort to order transfers with */
- bp->b_cylin = (bp->b_blkno + blockpersec(p->p_offset, lp)) /
- lp->d_secpercyl;
+ bp->b_cylinder = (bp->b_blkno + p->p_offset) / lp->d_secpercyl;
return(1);
bad:
bp->b_blkno = LABELSECTOR;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
- bp->b_cylin = LABELSECTOR / lp->d_secpercyl;
+ bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
(*strat)(bp);
if (biowait(bp)) {
msg = "I/O error";
- } else for (dlp = (struct disklabel *)bp->b_un.b_addr;
- dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp));
- dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+ } else {
+ dlp = (struct disklabel *)(bp->b_un.b_addr + LABELOFFSET);
if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
- if (msg == NULL) {
-#if defined(CD9660)
- if (iso_disklabelspoof(dev, strat, lp) != 0)
-#endif
- msg = "no disk label";
- }
+ msg = "no disk label";
} else if (dlp->d_npartitions > MAXPARTITIONS ||
- dkcksum(dlp) != 0)
+ dkcksum(dlp) != 0)
msg = "disk label corrupted";
else {
*lp = *dlp;
- msg = NULL;
- break;
}
}
bp->b_flags = B_INVAL | B_AGE;
return (msg);
}
+void
+dk_establish(p, q)
+ struct disk *p;
+ struct device *q;
+{
+}
+
/*
* Check new disk label for sensibility
* before setting it.
u_long openmask;
struct cpu_disklabel *osdep;
{
- register i;
+ register int i;
register struct partition *opp, *npp;
if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
disk_printtype(unit, type)
int unit, type;
{
- printf(" drive %d: %c%c", unit, MSCP_MID_CHAR(2, type),
- MSCP_MID_CHAR(1, type));
+ printf(" drive %d: %c%c", unit, (int)MSCP_MID_CHAR(2, type),
+ (int)MSCP_MID_CHAR(1, type));
if (MSCP_MID_ECH(0, type))
- printf("%c", MSCP_MID_CHAR(0, type));
+ printf("%c", (int)MSCP_MID_CHAR(0, type));
printf("%d\n", MSCP_MID_NUM(type));
}
struct pte *map;
int reg, flag;
{
+ struct proc *p;
volatile pt_entry_t *io;
pt_entry_t *pte;
struct pcb *pcb;
int pfnum, npf, o, i;
caddr_t addr;
- o = (int)bp->b_un.b_addr & PGOFSET;
- npf = btoc(bp->b_bcount + o) + 1;
+ o = (int)bp->b_un.b_addr & VAX_PGOFSET;
+ npf = vax_btoc(bp->b_bcount + o) + 1;
addr = bp->b_un.b_addr;
+ p = bp->b_proc;
/*
* Get a pointer to the pte pointing out the first virtual address.
*/
if ((bp->b_flags & B_PHYS) == 0) {
pte = kvtopte(addr);
+ if (p == 0)
+ p = &proc0;
} else {
- pcb = bp->b_proc->p_vmspace->vm_pmap.pm_pcb;
+ pcb = &p->p_addr->u_pcb;
pte = uvtopte(addr, pcb);
}
for (i = 0; i < (npf - 1); i++) {
if ((pte + i)->pg_pfn == 0) {
int rv;
- rv = vm_fault(&bp->b_proc->p_vmspace->vm_map,
- (unsigned)addr + i * NBPG,
- VM_PROT_READ|VM_PROT_WRITE, FALSE);
+ rv = uvm_fault(&p->p_vmspace->vm_map,
+ (unsigned)addr + i * VAX_NBPG, 0,
+ VM_PROT_READ|VM_PROT_WRITE);
if (rv)
panic("DMA to nonexistent page, %d", rv);
}
--- /dev/null
+/* $OpenBSD: findcpu.c,v 1.1 2000/04/27 01:10:09 bjc Exp $ */
+/* $NetBSD: findcpu.c,v 1.5 1999/08/23 19:10:43 ragge Exp $ */
+/*
+ * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
+ * 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 at Ludd, University of Lule}.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/device.h>
+
+#include <machine/sid.h>
+#include <machine/nexus.h>
+#include <machine/mtpr.h>
+#include <machine/cpu.h>
+
+/*
+ * We set up some information about the machine we're
+ * running on and thus initializes/uses vax_cputype and vax_boardtype.
+ * There should be no need to change/reinitialize these variables
+ * outside of this routine, they should be read only!
+ */
+int vax_cputype; /* highest byte of SID register */
+int vax_bustype; /* holds/defines all busses on this machine */
+int vax_boardtype; /* machine dependend, combination of SID and SIE */
+
+int vax_cpudata; /* contents of the SID register */
+int vax_siedata; /* contents of the SIE register */
+int vax_confdata; /* machine dependend, configuration/setup data */
+
+/*
+ * Try to figure out which type of system this is.
+ */
+void
+findcpu()
+{
+ vax_cpudata = mfpr(PR_SID);
+ vax_cputype = vax_cpudata >> 24;
+ vax_boardtype = vax_cputype << 24;
+
+ switch (vax_cputype) {
+ case VAX_TYP_780:
+ vax_bustype = VAX_SBIBUS;
+ break;
+ case VAX_TYP_750:
+ vax_bustype = VAX_CMIBUS;
+ break;
+ case VAX_TYP_790:
+ vax_bustype = VAX_ABUS;
+ break;
+
+ case VAX_TYP_UV2:
+ case VAX_TYP_CVAX:
+ case VAX_TYP_RIGEL:
+ case VAX_TYP_MARIAH:
+ case VAX_TYP_NVAX:
+ case VAX_TYP_SOC:
+ vax_siedata = *(int *)(0x20040004); /* SIE address */
+ vax_boardtype |= vax_siedata >> 24;
+
+ switch (vax_boardtype) {
+ case VAX_BTYP_420: /* They are very similar */
+ case VAX_BTYP_410:
+ case VAX_BTYP_43:
+ case VAX_BTYP_46:
+ case VAX_BTYP_48:
+ case VAX_BTYP_IS1:
+ vax_confdata = *(int *)(0x20020000);
+ case VAX_BTYP_49:
+ vax_bustype = VAX_VSBUS;
+ break;
+
+ case VAX_BTYP_9CC:
+ case VAX_BTYP_9RR:
+ case VAX_BTYP_1202:
+ case VAX_BTYP_1302:
+ vax_bustype = VAX_XMIBUS;
+ break;
+
+ case VAX_BTYP_670:
+ case VAX_BTYP_660:
+ case VAX_BTYP_60:
+ case VAX_BTYP_69D:
+ case VAX_BTYP_630:
+ case VAX_BTYP_650:
+ vax_bustype = VAX_IBUS;
+ break;
+
+ }
+ break;
+
+ case VAX_TYP_8SS:
+ vax_boardtype = VAX_BTYP_8000;
+ vax_bustype = VAX_BIBUS;
+ break;
+
+ case VAX_TYP_8NN:
+ case VAX_TYP_8PS:
+ vax_boardtype = VAX_BTYP_8800;
+ vax_bustype = VAX_NBIBUS;
+ break;
+
+ default:
+ /* CPU not supported, just give up */
+ asm("halt");
+ }
+}
--- /dev/null
+# $OpenBSD: genassym.cf,v 1.1 2000/04/27 01:10:11 bjc Exp $
+# $NetBSD: genassym.cf,v 1.10 1999/11/19 22:09:55 ragge Exp $
+#
+# Copyright (c) 1997 Ludd, University of Lule}, Sweden.
+# 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 at Ludd, University of
+# Lule}, Sweden and its contributors.
+# 4. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+include <sys/param.h>
+include <sys/proc.h>
+include <sys/errno.h>
+include <sys/syscall.h>
+
+include <net/netisr.h>
+
+include <machine/mtpr.h>
+include <machine/pcb.h>
+include <machine/sid.h>
+include <machine/trap.h>
+include <machine/cpu.h>
+
+define P_PRIORITY offsetof(struct proc, p_priority)
+define P_ADDR offsetof(struct proc, p_addr)
+define P_VMSPACE offsetof(struct proc, p_vmspace)
+
+define P0BR offsetof(struct pcb, P0BR)
+define P0LR offsetof(struct pcb, P0LR)
+define P1BR offsetof(struct pcb, P1BR)
+define P1LR offsetof(struct pcb, P1LR)
+define IFTRAP offsetof(struct pcb, iftrap)
+
+define MCHK offsetof(struct cpu_dep, cpu_mchk)
+define MEMERR offsetof(struct cpu_dep, cpu_memerr)
+
+define KERNBASE KERNBASE
+
+# mtpr register numbers
+define PR_KSP PR_KSP
+define PR_USP PR_USP
+define PR_ICCS PR_ICCS
+define PR_PCBB PR_PCBB
+define PR_IPL PR_IPL
+define PR_SBIFS PR_SBIFS
+define PR_EHSR PR_EHSR
+define PR_MCESR PR_MCESR
+define PR_P0BR PR_P0BR
+define PR_P1BR PR_P1BR
+define PR_P0LR PR_P0LR
+define PR_P1LR PR_P1LR
+define PR_SCBB PR_SCBB
+
+# trap numbering
+define T_KSPNOTVAL T_KSPNOTVAL
+define T_PRIVINFLT T_PRIVINFLT
+define T_XFCFLT T_XFCFLT
+define T_RESOPFLT T_RESOPFLT
+define T_RESADFLT T_RESADFLT
+define T_TRANSFLT T_TRANSFLT
+define T_PTEFETCH T_PTEFETCH
+define T_WRITE T_WRITE
+define T_ACCFLT T_ACCFLT
+define T_PTELEN T_PTELEN
+define T_TRCTRAP T_TRCTRAP
+define T_BPTFLT T_BPTFLT
+define T_ARITHFLT T_ARITHFLT
+define T_SYSCALL T_SYSCALL
+define T_ASTFLT T_ASTFLT
+define T_KDBTRAP T_KDBTRAP
+
+# software net interrupts
+define NETISR_IP NETISR_IP
+define NETISR_ARP NETISR_ARP
+define NETISR_NS NETISR_NS
+define NETISR_ATALK NETISR_ATALK
+define NETISR_ISO NETISR_ISO
+define NETISR_CCITT NETISR_CCITT
+define NETISR_PPP NETISR_PPP
+define NETISR_IPV6 NETISR_IPV6
+define NETISR_BRIDGE NETISR_BRIDGE
+
+define USPACE USPACE
+
+define ENAMETOOLONG ENAMETOOLONG
+
+define SYS_sigreturn SYS_sigreturn
+define SYS_exit SYS_exit
+
+define VAX_TYP_UV2 VAX_TYP_UV2
+define VAX_TYP_8SS VAX_TYP_8SS
+define VAX_BTYP_46 VAX_BTYP_46
+define VAX_BTYP_48 VAX_BTYP_48
-/* $OpenBSD: gencons.c,v 1.6 1997/09/10 12:04:45 maja Exp $ */
-/* $NetBSD: gencons.c,v 1.13 1997/03/15 16:36:19 ragge Exp $ */
+/* $OpenBSD: gencons.c,v 1.7 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: gencons.c,v 1.22 2000/01/24 02:40:33 matt Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
#include <machine/mtpr.h>
#include <machine/sid.h>
#include <machine/cpu.h>
+#include <machine/scb.h>
#include <machine/../vax/gencons.h>
-struct tty *gencn_tty[1];
-
-int consinied = 0;
-
-int gencnparam __P((struct tty *, struct termios *));
-void gencnstart __P((struct tty *));
-int gencnopen __P((dev_t, int, int, struct proc *));
-int gencnclose __P((dev_t, int, int, struct proc *));
-int gencnread __P((dev_t, struct uio *, int));
-int gencnwrite __P((dev_t, struct uio *, int));
-int gencnioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int gencngetc __P((dev_t));
-void gencnprobe __P((struct consdev *));
-void gencninit __P((struct consdev *));
-struct tty *gencntty __P((dev_t));
-void gencnrint __P((void));
-void gencntint __P((void));
-void gencnstop __P((struct tty *, int));
+static struct tty *gencn_tty[4];
+
+static int consopened = 0;
+static int maxttys = 1;
+
+static int pr_txcs[4] = {PR_TXCS, PR_TXCS1, PR_TXCS2, PR_TXCS3};
+static int pr_rxcs[4] = {PR_RXCS, PR_RXCS1, PR_RXCS2, PR_RXCS3};
+static int pr_txdb[4] = {PR_TXDB, PR_TXDB1, PR_TXDB2, PR_TXDB3};
+static int pr_rxdb[4] = {PR_RXDB, PR_RXDB1, PR_RXDB2, PR_RXDB3};
+
+cons_decl(gen);
+#ifdef DYNAMIC_DEVSW
+bcdev_decl(gencn);
+#else
+cdev_decl(gencn);
+#endif
+
+static int gencnparam __P((struct tty *, struct termios *));
+static void gencnstart __P((struct tty *));
+void gencnrint __P((void *));
+void gencntint __P((void *));
int
gencnopen(dev, flag, mode, p)
struct tty *tp;
unit = minor(dev);
- if (unit)
+ if (unit >= maxttys)
return ENXIO;
- if (gencn_tty[0] == NULL)
- gencn_tty[0] = ttymalloc();
+ if (gencn_tty[unit] == NULL)
+ gencn_tty[unit] = ttymalloc();
- tp = gencn_tty[0];
+ tp = gencn_tty[unit];
tp->t_oproc = gencnstart;
tp->t_param = gencnparam;
tp->t_dev = dev;
if ((tp->t_state & TS_ISOPEN) == 0) {
- tp->t_state |= TS_WOPEN;
ttychars(tp);
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
return EBUSY;
tp->t_state |= TS_CARR_ON;
- mtpr(GC_RIE, PR_RXCS); /* Turn on interrupts */
- mtpr(GC_TIE, PR_TXCS);
+ if (unit == 0)
+ consopened = 1;
+ mtpr(GC_RIE, pr_rxcs[unit]); /* Turn on interrupts */
+ mtpr(GC_TIE, pr_txcs[unit]);
return ((*linesw[tp->t_line].l_open)(dev, tp));
}
int flag, mode;
struct proc *p;
{
- struct tty *tp = gencn_tty[0];
+ struct tty *tp = gencn_tty[minor(dev)];
+ if (minor(dev) == 0)
+ consopened = 0;
(*linesw[tp->t_line].l_close)(tp, flag);
ttyclose(tp);
return (0);
gencntty(dev)
dev_t dev;
{
- return gencn_tty[0]; /* XXX */
+ return gencn_tty[minor(dev)];
}
int
struct uio *uio;
int flag;
{
- struct tty *tp = gencn_tty[0];
+ struct tty *tp = gencn_tty[minor(dev)];
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
struct uio *uio;
int flag;
{
- struct tty *tp = gencn_tty[0];
+ struct tty *tp = gencn_tty[minor(dev)];
+
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
int flag;
struct proc *p;
{
+ struct tty *tp = gencn_tty[minor(dev)];
int error;
- struct tty *tp = gencn_tty[0];
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return error;
error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0) return error;
+ if (error >= 0)
+ return error;
return ENOTTY;
}
if(cl->c_cc){
tp->t_state |= TS_BUSY;
ch = getc(cl);
- mtpr(ch, PR_TXDB);
+ mtpr(ch, pr_txdb[minor(tp->t_dev)]);
} else {
if (tp->t_state & TS_ASLEEP) {
tp->t_state &= ~TS_ASLEEP;
}
void
-gencnrint()
+gencnrint(arg)
+ void *arg;
{
- struct tty *tp;
- int i, j;
+ struct tty *tp = *(struct tty **) arg;
+ int unit = (struct tty **) arg - gencn_tty;
+ int i;
- tp = gencn_tty[0];
- i = mfpr(PR_RXDB) & 0377; /* Mask status flags etc... */
+ i = mfpr(pr_rxdb[unit]) & 0377; /* Mask status flags etc... */
#ifdef DDB
- j = kdbrint(i);
+ if (tp->t_dev == cn_tab->cn_dev) {
+ int j = kdbrint(i);
- if (j == 1) /* Escape received, just return */
- return;
+ if (j == 1) /* Escape received, just return */
+ return;
- if (j == 2) /* Second char wasn't 'D' */
- (*linesw[tp->t_line].l_rint)(27, tp);
+ if (j == 2) /* Second char wasn't 'D' */
+ (*linesw[tp->t_line].l_rint)(27, tp);
+ }
#endif
- (*linesw[tp->t_line].l_rint)(i,tp);
+ (*linesw[tp->t_line].l_rint)(i, tp);
return;
}
-void
+int
gencnstop(tp, flag)
struct tty *tp;
int flag;
}
void
-gencntint()
+gencntint(arg)
+ void *arg;
{
- struct tty *tp;
+ struct tty *tp = *(struct tty **) arg;
- tp = gencn_tty[0];
tp->t_state &= ~TS_BUSY;
gencnstart(tp);
gencnprobe(cndev)
struct consdev *cndev;
{
- int i;
-
if ((vax_cputype < VAX_TYP_UV1) || /* All older has MTPR console */
(vax_boardtype == VAX_BTYP_630) ||
+ (vax_boardtype == VAX_BTYP_670) ||
(vax_boardtype == VAX_BTYP_650)) {
cndev->cn_dev = makedev(25, 0);
cndev->cn_pri = CN_NORMAL;
gencninit(cndev)
struct consdev *cndev;
{
+
+ /* Allocate interrupt vectors */
+ scb_vecalloc(SCB_G0R, gencnrint, &gencn_tty[0], SCB_ISTACK);
+ scb_vecalloc(SCB_G0T, gencntint, &gencn_tty[0], SCB_ISTACK);
+
+ if (vax_cputype == VAX_TYP_8SS) {
+ maxttys = 4;
+ scb_vecalloc(SCB_G1R, gencnrint, &gencn_tty[1], SCB_ISTACK);
+ scb_vecalloc(SCB_G1T, gencntint, &gencn_tty[1], SCB_ISTACK);
+
+ scb_vecalloc(SCB_G2R, gencnrint, &gencn_tty[2], SCB_ISTACK);
+ scb_vecalloc(SCB_G2T, gencntint, &gencn_tty[2], SCB_ISTACK);
+
+ scb_vecalloc(SCB_G3R, gencnrint, &gencn_tty[3], SCB_ISTACK);
+ scb_vecalloc(SCB_G3T, gencntint, &gencn_tty[3], SCB_ISTACK);
+ }
+ mtpr(0, PR_TBIA); /* ??? */
}
void
i = 10;
return i;
}
+
+void
+gencnpollc(dev, pollflag)
+ dev_t dev;
+ int pollflag;
+{
+ if (pollflag) {
+ mtpr(0, PR_RXCS);
+ mtpr(0, PR_TXCS);
+ } else if (consopened) {
+ mtpr(GC_RIE, PR_RXCS);
+ mtpr(GC_TIE, PR_TXCS);
+ }
+}
-/* $OpenBSD: gencons.h,v 1.3 1997/05/29 00:05:18 niklas Exp $ */
-/* $NetBSD: gencons.h,v 1.5 1996/04/08 18:32:37 ragge Exp $ */
+/* $OpenBSD: gencons.h,v 1.4 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: gencons.h,v 1.9 2000/01/20 00:07:49 matt Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
*/
/* All bugs are subject to removal without further notice */
-
/*
* Some definitions for generic console interface (PR 32-35)
/* PR_TXCS */
#define GC_RDY 0x80 /* Console ready to xmit chr */
#define GC_TIE 0x40 /* xmit interrupt enable */
-#if VAX8600
-#define GC_LT 0x80000 /* Enable logical terminal */
-#define GC_WRT 0x8000 /* Allow mtpr's to console */
-#endif
+#define GC_LT 0x80000 /* VAX8600: Enable logical terminal */
+#define GC_WRT 0x8000 /* VAX8600: Allow mtpr's to console */
/* PR_RXCS */
#define GC_DON 0x80 /* character received */
#define GC_CON 0xf00 /* mfpr($PR_RXDB)&GC_CON==0 then console chr */
/* PR_TXDB */
-#define GC_BOOT 0xf02 /* boot machine */
-#define GC_CCF 0xf04 /* clear cold start flag */
+#define GC_CONS 0xf00 /* Console software !8600 */
+#define GC_BTFL 0x2 /* boot machine */
+#define GC_CWFL 0x3 /* clear warm start flag */
+#define GC_CCFL 0x4 /* clear cold start flag */
+
+/* Interrupt vectors used */
+#define SCB_G0R 0xf8
+#define SCB_G0T 0xfc
+#define SCB_G1R 0xc8
+#define SCB_G1T 0xcc
+#define SCB_G2R 0xd0
+#define SCB_G2T 0xd4
+#define SCB_G3R 0xd8
+#define SCB_G3T 0xdc
/* Prototypes */
void gencnputc __P((dev_t, int));
--- /dev/null
+/* $OpenBSD: ibus.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: ibus.c,v 1.2 1999/08/14 18:42:46 ragge Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <machine/nexus.h>
+#include <machine/cpu.h>
+#include <machine/sid.h>
+
+static int ibus_print __P((void *, const char *));
+static int ibus_match __P((struct device *, struct cfdata *, void *));
+static void ibus_attach __P((struct device *, struct device *, void*));
+
+struct cfdriver ibus_cd = {
+ NULL, "ibus", DV_DULL
+};
+
+struct cfattach ibus_ca = {
+ sizeof(struct device), (cfmatch_t)ibus_match, ibus_attach
+};
+
+int
+ibus_print(aux, name)
+ void *aux;
+ const char *name;
+{
+ struct bp_conf *bp = aux;
+
+ if (name)
+ printf("device %s at %s", bp->type, name);
+
+ return (UNCONF);
+}
+
+
+int
+ibus_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ if (vax_bustype == VAX_IBUS)
+ return 1;
+ return 0;
+}
+
+#define MVNIADDR 0x20084400
+#define SGECADDR 0x20008000
+#define SHACADDR 0x20004200
+
+void
+ibus_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct bp_conf bp;
+ vaddr_t va;
+
+ printf("\n");
+ /*
+ * There may be a SGEC. Is badaddr() enough here?
+ */
+ bp.type = "sgec";
+ va = vax_map_physmem(SGECADDR, 1);
+ if (badaddr((caddr_t)va, 4) == 0)
+ config_found(self, &bp, ibus_print);
+ vax_unmap_physmem(va, 1);
+
+ /*
+ * There may be a LANCE.
+ */
+ bp.type = "lance";
+ va = vax_map_physmem(MVNIADDR, 1);
+ if (badaddr((caddr_t)va, 2) == 0)
+ config_found(self, &bp, ibus_print);
+ vax_unmap_physmem(va, 1);
+
+ /*
+ * The same procedure for SHAC.
+ */
+ bp.type = "shac";
+ va = vax_map_physmem(SHACADDR, 1);
+ if (badaddr((caddr_t)va + 0x48, 4) == 0)
+ config_found(self, &bp, ibus_print);
+ vax_unmap_physmem(va, 1);
+ /*
+ * All MV's have a Qbus.
+ */
+ bp.type = "uba";
+ config_found(self, &bp, ibus_print);
+
+}
-/* $OpenBSD: intvec.s,v 1.11 1998/05/11 16:24:43 niklas Exp $ */
-/* $NetBSD: intvec.s,v 1.23 1997/07/28 21:48:35 ragge Exp $ */
+/* $OpenBSD: intvec.s,v 1.12 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: intvec.s,v 1.39 1999/06/28 08:20:48 itojun Exp $ */
/*
- * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1994, 1997 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- /* All bugs are subject to removal without further notice */
-
+#include "assym.h"
-#include <machine/mtpr.h>
-#include <machine/pte.h>
-#include <machine/trap.h>
+#include "ppp.h"
+#include "bridge.h"
#define ENTRY(name) \
.text ; \
popr $0x3f ; \
rei
-#define STRAY(scbnr, vecnr) \
-ENTRY(stray/**/vecnr) ; \
- pushr $0x3f ; \
- pushl $/**/0x/**/vecnr ; \
- pushl $scbnr ; \
- calls $2,_stray ; \
- popr $0x3f ; \
- rei
+#define PUSHR pushr $0x3f
+#define POPR popr $0x3f
#define KSTACK 0
#define ISTACK 1
+#define NOVEC .long 0
#define INTVEC(label,stack) \
.long label+stack;
.text
- .globl _kernel_text, _kernbase, _rpb
-_kernel_text:
+ .globl _kernbase, _rpb, _kernel_text
+ .set _kernel_text,KERNBASE
_kernbase:
_rpb:
/*
* and move the SCB later to somewhere else.
*/
- INTVEC(stray00, ISTACK) # Unused., 0
+ NOVEC; # Unused, 0
INTVEC(mcheck, ISTACK) # Machine Check., 4
- INTVEC(invkstk, ISTACK) # Kernel Stack Invalid., 8
- INTVEC(stray0C, ISTACK) # Power Failed., C
+ INTVEC(invkstk, ISTACK) # Kernel Stack Invalid., 8
+ NOVEC; # Power Failed., C
INTVEC(privinflt, KSTACK) # Privileged/Reserved Instruction.
INTVEC(xfcflt, KSTACK) # Customer Reserved Instruction, 14
INTVEC(resopflt, KSTACK) # Reserved Operand/Boot Vector(?), 18
- INTVEC(resadflt, KSTACK) # # Reserved Address Mode., 1C
+ INTVEC(resadflt, KSTACK) # Reserved Address Mode., 1C
INTVEC(access_v, KSTACK) # Access Control Violation, 20
INTVEC(transl_v, KSTACK) # Translation Invalid, 24
- INTVEC(tracep, KSTACK) # Trace Pending, 28
- INTVEC(breakp, KSTACK) # Breakpoint Instruction, 2C
- INTVEC(stray30, ISTACK) # Compatibility Exception, 30
+ INTVEC(tracep, KSTACK) # Trace Pending, 28
+ INTVEC(breakp, KSTACK) # Breakpoint Instruction, 2C
+ NOVEC; # Compatibility Exception, 30
INTVEC(arithflt, KSTACK) # Arithmetic Fault, 34
- INTVEC(stray38, ISTACK) # Unused, 38
- INTVEC(stray3C, ISTACK) # Unused, 3C
+ NOVEC; # Unused, 38
+ NOVEC; # Unused, 3C
INTVEC(syscall, KSTACK) # main syscall trap, chmk, 40
INTVEC(resopflt, KSTACK) # chme, 44
INTVEC(resopflt, KSTACK) # chms, 48
INTVEC(resopflt, KSTACK) # chmu, 4C
- INTVEC(sbiexc, ISTACK) # System Backplane Exception/BIerror, 50
- INTVEC(cmrerr, ISTACK) # Corrected Memory Read, 54
- INTVEC(rxcs, ISTACK) # System Backplane Alert/RXCD, 58
- INTVEC(sbiflt, ISTACK) # System Backplane Fault, 5C
- INTVEC(stray60, ISTACK) # Memory Write Timeout, 60
- INTVEC(stray64, ISTACK) # Unused, 64
- INTVEC(stray68, ISTACK) # Unused, 68
- INTVEC(stray6C, ISTACK) # Unused, 6C
- INTVEC(stray70, ISTACK) # Unused, 70
- INTVEC(stray74, ISTACK) # Unused, 74
- INTVEC(stray78, ISTACK) # Unused, 78
- INTVEC(stray7C, ISTACK) # Unused, 7C
- INTVEC(stray80, ISTACK) # Unused, 80
- INTVEC(stray84, ISTACK) # Unused, 84
- INTVEC(astintr, KSTACK) # Asynchronous Sustem Trap, AST
- INTVEC(stray8C, ISTACK) # Unused, 8C
- INTVEC(stray90, ISTACK) # Unused, 90
- INTVEC(stray94, ISTACK) # Unused, 94
- INTVEC(stray98, ISTACK) # Unused, 98
- INTVEC(stray9C, ISTACK) # Unused, 9C
+ NOVEC; # System Backplane Exception/BIerror, 50
+ INTVEC(cmrerr, ISTACK) # Corrected Memory Read, 54
+ NOVEC; # System Backplane Alert/RXCD, 58
+ INTVEC(sbiflt, ISTACK) # System Backplane Fault, 5C
+ NOVEC; # Memory Write Timeout, 60
+ NOVEC; # Unused, 64
+ NOVEC; # Unused, 68
+ NOVEC; # Unused, 6C
+ NOVEC; # Unused, 70
+ NOVEC; # Unused, 74
+ NOVEC; # Unused, 78
+ NOVEC; # Unused, 7C
+ NOVEC; # Unused, 80
+ NOVEC; # Unused, 84
+ INTVEC(astintr, KSTACK) # Asynchronous Sustem Trap, AST
+ NOVEC; # Unused, 8C
+ NOVEC; # Unused, 90
+ NOVEC; # Unused, 94
+ NOVEC; # Unused, 98
+ NOVEC; # Unused, 9C
INTVEC(softclock,ISTACK) # Software clock interrupt
- INTVEC(strayA4, ISTACK) # Unused, A4
- INTVEC(strayA8, ISTACK) # Unused, A8
- INTVEC(strayAC, ISTACK) # Unused, AC
- INTVEC(netint, ISTACK) # Network interrupt
- INTVEC(strayB4, ISTACK) # Unused, B4
- INTVEC(strayB8, ISTACK) # Unused, B8
- INTVEC(ddbtrap, ISTACK) # Kernel debugger trap, BC
+ NOVEC; # Unused, A4
+ NOVEC; # Unused, A8
+ NOVEC; # Unused, AC
+ INTVEC(netint, ISTACK) # Network interrupt
+ NOVEC; # Unused, B4
+ NOVEC; # Unused, B8
+ INTVEC(ddbtrap, ISTACK) # Kernel debugger trap, BC
INTVEC(hardclock,ISTACK) # Interval Timer
- INTVEC(strayC4, ISTACK) # Unused, C4
- INTVEC(emulate, KSTACK) # Subset instruction emulation
- INTVEC(strayCC, ISTACK) # Unused, CC
- INTVEC(strayD0, ISTACK) # Unused, D0
- INTVEC(strayD4, ISTACK) # Unused, D4
- INTVEC(strayD8, ISTACK) # Unused, D8
- INTVEC(strayDC, ISTACK) # Unused, DC
- INTVEC(strayE0, ISTACK) # Unused, E0
- INTVEC(strayE4, ISTACK) # Unused, E4
- INTVEC(strayE8, ISTACK) # Unused, E8
- INTVEC(strayEC, ISTACK) # Unused, EC
- INTVEC(strayF0, ISTACK)
- INTVEC(strayF4, ISTACK)
-#if VAX8600 || VAX8200 || VAX750 || VAX780 || VAX630 || VAX650
- INTVEC(consrint, ISTACK) # Console Terminal Recieve Interrupt
- INTVEC(constint, ISTACK) # Console Terminal Transmit Interrupt
-#else
- INTVEC(strayF8, ISTACK)
- INTVEC(strayFC, ISTACK)
-#endif
+ NOVEC; # Unused, C4
+ INTVEC(emulate, KSTACK) # Subset instruction emulation, C8
+ NOVEC; # Unused, CC
+ NOVEC; # Unused, D0
+ NOVEC; # Unused, D4
+ NOVEC; # Unused, D8
+ NOVEC; # Unused, DC
+ NOVEC; # Unused, E0
+ NOVEC; # Unused, E4
+ NOVEC; # Unused, E8
+ NOVEC; # Unused, EC
+ NOVEC;
+ NOVEC;
+ NOVEC;
+ NOVEC;
/* space for adapter vectors */
.space 0x100
- STRAY(0,00)
-
.align 2
#
# mcheck is the badaddress trap, also called when referencing
tstl _cold # Ar we still in coldstart?
bneq L4 # Yes.
- pushr $0x3f
+ pushr $0x7f
pushab 24(sp)
- calls $1, _machinecheck
- popr $0x3f
+ movl _dep_call,r6 # CPU dependent mchk handling
+ calls $1,*MCHK(r6)
+ tstl r0 # If not machine check, try memory error
+ beql 1f
+ calls $0,*MEMERR(r6)
+ pushab 2f
+ calls $1,_panic
+2: .asciz "mchk"
+1: popr $0x7f
addl2 (sp)+,sp
rei
rei
TRAPCALL(invkstk, T_KSPNOTVAL)
- STRAY(0,0C)
TRAPCALL(privinflt, T_PRIVINFLT)
TRAPCALL(xfcflt, T_XFCFLT);
TRAPCALL(resopflt, T_RESOPFLT)
TRAPCALL(resadflt, T_RESADFLT)
+/*
+ * Translation fault, used only when simulating page reference bit.
+ * Therefore it is done a fast revalidation of the page if it is
+ * referenced. Trouble here is the hardware bug on KA650 CPUs that
+ * put in a need for an extra check when the fault is gotten during
+ * PTE reference. Handled in pmap.c.
+ */
.align 2
-transl_v: .globl transl_v # Translation violation, 20
- pushl $T_TRANSFLT
-L3: bbc $1,4(sp),L1
- bisl2 $T_PTEFETCH, (sp)
-L1: bbc $2,4(sp),L2
- bisl2 $T_WRITE, (sp)
-L2: movl (sp), 4(sp)
- addl2 $4, sp
- jbr trap
-
+transl_v: .globl transl_v # Translation violation, 20
+ pushr $0x3f
+ pushl 28(sp)
+ pushl 28(sp)
+ calls $2,_pmap_simulref
+ tstl r0
+ bneq 1f
+ popr $0x3f
+ addl2 $8,sp
+ rei
+1: popr $0x3f
+ brb access_v
.align 2
access_v:.globl access_v # Access cntrl viol fault, 24
blbs (sp), ptelen
pushl $T_ACCFLT
- jbr L3
+ bbc $1,4(sp),1f
+ bisl2 $T_PTEFETCH,(sp)
+1: bbc $2,4(sp),2f
+ bisl2 $T_WRITE,(sp)
+2: movl (sp), 4(sp)
+ addl2 $4, sp
+ jbr trap
ptelen: movl $T_PTELEN, (sp) # PTE must expand (or send segv)
jbr trap;
TRAPCALL(tracep, T_TRCTRAP)
TRAPCALL(breakp, T_BPTFLT)
- STRAY(0,30)
TRAPARGC(arithflt, T_ARITHFLT)
- STRAY(0,38)
- STRAY(0,3C)
-
-
-
-
-
- .align 2 # Main system call
- .globl syscall
-syscall:
+ENTRY(syscall) # Main system call
pushl $T_SYSCALL
pushr $0xfff
mfpr $PR_USP, -(sp)
mtpr $0x1f, $PR_IPL # Be sure we can REI
rei
- STRAY(0,44)
- STRAY(0,48)
- STRAY(0,4C)
-ENTRY(sbiexc)
- tstl _cold /* Is it ok to get errs during boot??? */
- bneq 1f
- pushr $0x3f
- pushl $0x50
- pushl $0
- calls $2,_stray
- popr $0x3f
-1: rei
-
- FASTINTR(cmrerr,cmrerr)
-
-ENTRY(rxcs); /* console interrupt from some other processor */
- pushr $0x3f
-#if VAX8200
- cmpl $5,_vax_cputype
- bneq 1f
- calls $0,_rxcdintr
- brb 2f
-#endif
-1: pushl $0x58
- pushl $0
- calls $2,_stray
-2: popr $0x3f
+ENTRY(cmrerr)
+ PUSHR
+ movl _dep_call,r0
+ calls $0,*MEMERR(r0)
+ POPR
rei
- ENTRY(sbiflt);
- moval sbifltmsg, -(sp)
+ENTRY(sbiflt);
+ movab sbifltmsg, -(sp)
calls $1, _panic
- STRAY(0,60)
- STRAY(0,64)
- STRAY(0,68)
- STRAY(0,6C)
- STRAY(0,70)
- STRAY(0,74)
- STRAY(0,78)
- STRAY(0,7C)
- STRAY(0,80)
- STRAY(0,84)
-
TRAPCALL(astintr, T_ASTFLT)
- STRAY(0,8C)
- STRAY(0,90)
- STRAY(0,94)
- STRAY(0,98)
- STRAY(0,9C)
-
FASTINTR(softclock,softclock)
- STRAY(0,A4)
- STRAY(0,A8)
- STRAY(0,AC)
-
- FASTINTR(netint,netintr) #network packet interrupt
+ENTRY(netint)
+ PUSHR
+#ifdef INET
+ bbcc $NETISR_ARP,_netisr,1f; calls $0,_arpintr; 1:
+ bbcc $NETISR_IP,_netisr,1f; calls $0,_ipintr; 1:
+#endif
+#ifdef INET6
+ bbcc $NETISR_IPV6,_netisr,1f; calls $0,_ip6intr; 1:
+#endif
+#ifdef NETATALK
+ bbcc $NETISR_ATALK,_netisr,1f; calls $0,_atintr; 1:
+#endif
+#ifdef NS
+ bbcc $NETISR_NS,_netisr,1f; calls $0,_nsintr; 1:
+#endif
+#ifdef ISO
+ bbcc $NETISR_ISO,_netisr,1f; calls $0,_clnlintr; 1:
+#endif
+#ifdef CCITT
+ bbcc $NETISR_CCITT,_netisr,1f; calls $0,_ccittintr; 1:
+#endif
+#if NPPP > 0
+ bbcc $NETISR_PPP,_netisr,1f; calls $0,_pppintr; 1:
+#endif
+#if NBRIDGE > 0
+ bbcc $NETISR_BRIDGE,_netisr,1f; calls $0, _bridgeintr; 1:
+#endif
+ POPR
+ rei
- STRAY(0,B4)
- STRAY(0,B8)
TRAPCALL(ddbtrap, T_KDBTRAP)
.align 2
.globl hardclock
hardclock: mtpr $0xc1,$PR_ICCS # Reset interrupt flag
pushr $0x3f
- pushl sp
+#ifdef VAX46
+ cmpl _vax_boardtype,$VAX_BTYP_46
+ bneq 1f
+ movl _ka46_cpu,r0
+ clrl 0x1c(r0)
+#endif
+1: pushl sp
addl2 $24,(sp)
calls $1,_hardclock
popr $0x3f
rei
- STRAY(0,C4)
- STRAY(0,CC)
- STRAY(0,D0)
- STRAY(0,D4)
- STRAY(0,D8)
- STRAY(0,DC)
- STRAY(0,E0)
- STRAY(0,E4)
- STRAY(0,E8)
- STRAY(0,EC)
- STRAY(0,F0)
- STRAY(0,F4)
-#if VAX8600 || VAX8200 || VAX750 || VAX780 || VAX630 || VAX650
- FASTINTR(consrint,gencnrint)
- FASTINTR(constint,gencntint)
-#else
- STRAY(0,F8)
- STRAY(0,FC)
-#endif
-
/*
* Main routine for traps; all go through this.
* Note that we put USP on the frame here, which sometimes should
rei
sbifltmsg:
- .asciz "SBI fault",0
+ .asciz "SBI fault"
#if VAX630 || VAX650 || VAX410
/*
-/* $OpenBSD: ka410.c,v 1.5 1997/09/20 14:04:31 maja Exp $ */
-/* $NetBSD: ka410.c,v 1.7 1997/07/26 10:12:45 ragge Exp $ */
+/* $OpenBSD: ka410.c,v 1.6 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka410.c,v 1.21 1999/09/06 19:52:53 ragge Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
#include <sys/types.h>
#include <sys/device.h>
#include <sys/kernel.h>
+#include <sys/systm.h>
+
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/nexus.h>
#include <machine/uvax.h>
#include <machine/ka410.h>
+#include <machine/ka420.h>
#include <machine/clock.h>
+#include <machine/vsbus.h>
-static void ka410_conf __P((struct device*, struct device*, void*));
-static void ka410_memenable __P((struct sbi_attach_args*, struct device *));
-static void ka410_steal_pages __P((void));
+static void ka410_conf __P((void));
static void ka410_memerr __P((void));
static int ka410_mchk __P((caddr_t));
static void ka410_halt __P((void));
static void ka410_reboot __P((int));
+static void ka41_cache_enable __P((void));
+static void ka410_clrf __P((void));
-extern short *clk_page;
-
-static struct uc_map ka410_map[] = {
- { KA410_CFGTST, KA410_CFGTST+1023, 1024, 0 },
- { KA410_ROM_BASE, KA410_ROM_END, KA410_ROM_SIZE, 0 },
- { (int)KA410_CPU_BASE, KA410_CPU_END, KA410_CPU_SIZE, 0 },
- { KA410_NWA_BASE, KA410_NWA_END, KA410_NWA_SIZE, 0 },
- { KA410_SER_BASE, KA410_SER_END, KA410_SER_SIZE, 0 },
- { (int)KA410_WAT_BASE, KA410_WAT_END, KA410_WAT_SIZE, 0 },
-#if 0
- { KA410_SCS_BASE, KA410_SCS_END, KA410_SCS_SIZE, 0 },
-#else
- { 0x200C0000, 0x200C01FF, 0x200, 0 },
-#endif
- { KA410_LAN_BASE, KA410_LAN_END, KA410_LAN_SIZE, 0 },
- { KA410_CUR_BASE, KA410_CUR_END, KA410_CUR_SIZE, 0 },
- { KA410_DMA_BASE, KA410_DMA_END, KA410_DMA_SIZE, 0 },
- /*
- * there's more to come, eg. framebuffers (mono + GPX)
- */
- {0, 0, 0, 0},
-};
+static caddr_t l2cache; /* mapped in address */
+static long *cacr; /* l2csche ctlr reg */
/*
* Declaration of 410-specific calls.
*/
struct cpu_dep ka410_calls = {
- ka410_steal_pages,
- no_nicr_clock,
+ 0,
ka410_mchk,
ka410_memerr,
ka410_conf,
chip_clkread,
chip_clkwrite,
1, /* ~VUPS */
- (void*)KA410_INTREQ, /* Used by vaxstation */
- (void*)KA410_INTCLR, /* Used by vaxstation */
- (void*)KA410_INTMSK, /* Used by vaxstation */
- ka410_map,
+ 2, /* SCB pages */
ka410_halt,
ka410_reboot,
+ ka410_clrf,
};
void
-ka410_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka410_conf()
{
- extern char cpu_model[];
+ struct vs_cpu *ka410_cpu;
+
+ ka410_cpu = (struct vs_cpu *)vax_map_physmem(VS_REGS, 1);
switch (vax_cputype) {
case VAX_TYP_UV2:
- if (vax_confdata & 0x80) /* MSB in CFGTST */
- strcpy(cpu_model,"MicroVAX 2000");
- else
- strcpy(cpu_model,"VAXstation 2000");
+ ka410_cpu->vc_410mser = 1;
+ printf("cpu: KA410\n");
break;
case VAX_TYP_CVAX:
- /* if (((vax_siedata >> 8) & 0xff) == 2) */
- strcpy(cpu_model,"VAXstation 3100 model 10-48");
- /* ka41_cache_enable(); */
+ printf("cpu: KA41/42\n");
+ ka410_cpu->vc_vdcorg = 0; /* XXX */
+ ka410_cpu->vc_parctl = PARCTL_CPEN | PARCTL_DPEN ;
+ printf("cpu: Enabling primary cache, ");
+ mtpr(KA420_CADR_S2E|KA420_CADR_S1E|KA420_CADR_ISE|KA420_CADR_DSE,
+ PR_CADR);
+ if (vax_confdata & KA420_CFG_CACHPR) {
+ l2cache = (void *)vax_map_physmem(KA420_CH2_BASE,
+ (KA420_CH2_SIZE / VAX_NBPG));
+ cacr = (void *)vax_map_physmem(KA420_CACR, 1);
+ printf("secondary cache\n");
+ ka41_cache_enable();
+ } else
+ printf("no secondary cache present\n");
}
+ /* Done with ka410_cpu - release it */
+ vax_unmap_physmem((vaddr_t)ka410_cpu, 1);
+ /*
+ * Setup parameters necessary to read time from clock chip.
+ */
+ clk_adrshift = 1; /* Addressed at long's... */
+ clk_tweak = 2; /* ...and shift two */
+ clk_page = (short *)vax_map_physmem(KA420_WAT_BASE, 1);
+}
- printf(": %s\n", cpu_model);
+void
+ka41_cache_enable()
+{
+ *cacr = KA420_CACR_TPE; /* Clear any error, disable cache */
+ bzero(l2cache, KA420_CH2_SIZE); /* Clear whole cache */
+ *cacr = KA420_CACR_CEN; /* Enable cache */
}
void
caddr_t addr;
{
panic("Machine check");
-}
-
-u_long le_iomem; /* base addr of RAM -- CPU's view */
-u_long le_ioaddr; /* base addr of RAM -- LANCE's view */
-
-void
-ka410_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail, avail_end;
- extern int clk_adrshift, clk_tweak;
- int junk;
-
- int i;
- struct {
- u_long :2;
- u_long data:8;
- u_long :22;
- } *p;
- int *srp; /* Scratch Ram */
- char *q = (void*)&srp;
-
- srp = NULL;
- p = (void*)KA410_SCR;
- for (i=0; i<4; i++) {
- printf("p[%d] = %x, ", i, p[i].data);
- q[i] = p[i].data;
- }
- p = (void*)KA410_SCRLEN;
- printf("\nlen = %d\n", p->data);
- printf("srp = 0x%x\n", srp);
-
- for (i=0; i<0x2; i++) {
- printf("%x:0x%x ", i*4, srp[i]);
- if ((i & 0x07) == 0x07)
- printf("\n");
- }
- printf("\n");
-
- /*
- * SCB is already copied/initialized at addr avail_start
- * by pmap_bootstrap(), but it's not yet mapped. Thus we use
- * the MAPPHYS() macro to reserve these two pages and to
- * perform the mapping. The mapped address is assigned to junk.
- */
- MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE);
-
- clk_adrshift = 1; /* Addressed at long's... */
- clk_tweak = 2; /* ...and shift two */
- MAPVIRT(clk_page, 2);
- pmap_map((vm_offset_t)clk_page, (vm_offset_t)KA410_WAT_BASE,
- (vm_offset_t)KA410_WAT_BASE + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- /*
- * At top of physical memory there are some console-prom and/or
- * restart-specific data. Make this area unavailable.
- */
- avail_end -= 10 * NBPG;
-
- /*
- * If we need to map physical areas also, we can decrease avail_end
- * (the highest available memory-address), copy the stuff into the
- * gap between and use pmap_map to map it...
- *
- * Don't use the MAPPHYS macro here, since this uses and changes(!)
- * the value of avail_start. Use MAPVIRT even if it's name misleads.
- */
- avail_end -= 10 * NBPG; /* paranoid: has been done before */
-
- avail_end = (int)srp;
-
- avail_end &= ~0xffff; /* make avail_end 64K-aligned */
- avail_end -= (64 * 1024); /* steal 64K for LANCE's iobuf */
- le_ioaddr = avail_end; /* ioaddr=phys, iomem=virt */
- MAPVIRT(le_iomem, (64 * 1024)/NBPG);
- pmap_map((vm_offset_t)le_iomem, le_ioaddr, le_ioaddr + 0xffff,
- VM_PROT_READ|VM_PROT_WRITE);
-
- printf("le_iomem: %x, le_ioaddr: %x, srp: %x, avail_end: %x\n",
- le_iomem, le_ioaddr, srp, avail_end);
-
- /*
- * VAXstation 2000 and MicroVAX 2000:
- * since there's no bus, we have to map in anything which
- * could be neccessary/used/interesting...
- *
- * MAPVIRT(ptr,count) reserves a virtual area with the requested size
- * and initializes ptr to point at this location
- * pmap_map(ptr,...) inserts a pair of virtual/physical addresses
- * into the system maptable (Sysmap)
- */
- uvax_fillmap();
-
- /*
- * Clear restart and boot in progress flags
- * in the CPMBX. (ie. clear bits 4 and 5)
- */
- KA410_WAT_BASE->cpmbx = (KA410_WAT_BASE->cpmbx & ~0x30);
-
- /*
- * Enable memory parity error detection and clear error bits.
- */
- KA410_CPU_BASE->ka410_mser = 1;
- /* (UVAXIIMSER_PEN | UVAXIIMSER_MERR | UVAXIIMSER_LEB); */
-
+ return 0;
}
static void
asm("movl $0xc, (%0)"::"r"((int)clk_page + 0x38)); /* Don't ask */
asm("halt");
}
+
+static void
+ka410_clrf()
+{
+ struct ka410_clock *clk = (void *)clk_page;
+
+ /*
+ * Clear restart and boot in progress flags
+ * in the CPMBX. (ie. clear bits 4 and 5)
+ */
+ clk->cpmbx = (clk->cpmbx & ~0x30);
+}
-/* $OpenBSD: ka43.c,v 1.4 1999/01/11 05:12:08 millert Exp $ */
-/* $NetBSD: ka43.c,v 1.5 1997/04/18 18:53:38 ragge Exp $ */
+/* $OpenBSD: ka43.c,v 1.5 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka43.c,v 1.19 1999/09/06 19:52:53 ragge Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
#include <sys/types.h>
#include <sys/device.h>
#include <sys/kernel.h>
+#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/pmap.h>
#include <machine/nexus.h>
#include <machine/uvax.h>
+#include <machine/vsbus.h>
#include <machine/ka43.h>
#include <machine/clock.h>
-void ka43_conf __P((struct device*, struct device*, void*));
-void ka43_steal_pages __P((void));
-
-int ka43_mchk __P((caddr_t));
-void ka43_memerr __P((void));
-
-int ka43_clear_errors __P((void));
-
-int ka43_cache_init __P((void)); /* "int mapen" as argument? */
-int ka43_cache_reset __P((void));
-int ka43_cache_enable __P((void));
-int ka43_cache_disable __P((void));
-int ka43_cache_invalidate __P((void));
-
-static struct uc_map ka43_map[] = {
- { KA43_CFGTST, KA43_CFGTST, 4, 0 },
- { KA43_ROM_BASE, KA43_ROM_END, KA43_ROM_SIZE, 0 },
- { KA43_CPU_BASE, KA43_CPU_END, KA43_CPU_SIZE, 0 },
- { KA43_CT2_BASE, KA43_CT2_END, KA43_CT2_SIZE, 0 },
- { KA43_CH2_CREG, KA43_CH2_CREG, 4, 0 },
- { KA43_NWA_BASE, KA43_NWA_END, KA43_NWA_SIZE, 0 },
- { KA43_SER_BASE, KA43_SER_END, KA43_SER_SIZE, 0 },
- { KA43_WAT_BASE, KA43_WAT_END, KA43_WAT_SIZE, 0 },
- { KA43_SCS_BASE, KA43_SCS_END, KA43_SCS_SIZE, 0 },
- { KA43_LAN_BASE, KA43_LAN_END, KA43_LAN_SIZE, 0 },
- { KA43_CUR_BASE, KA43_CUR_END, KA43_CUR_SIZE, 0 },
- { KA43_DMA_BASE, KA43_DMA_END, KA43_DMA_SIZE, 0 },
- { KA43_VME_BASE, KA43_VME_END, KA43_VME_SIZE, 0 },
- /*
- * there's more to come, eg. framebuffers (GPX/SPX)
- */
- {0, 0, 0, 0},
-};
+static void ka43_conf __P((void));
+static void ka43_steal_pages __P((void));
+
+static int ka43_mchk __P((caddr_t));
+static void ka43_memerr __P((void));
+#if 0
+static void ka43_clear_errors __P((void));
+#endif
+static int ka43_cache_init __P((void)); /* "int mapen" as argument? */
+static int ka43_cache_reset __P((void));
+static int ka43_cache_enable __P((void));
+static int ka43_cache_disable __P((void));
+static int ka43_cache_invalidate __P((void));
+static void ka43_halt __P((void));
+static void ka43_reboot __P((int));
+static void ka43_clrf __P((void));
+
struct cpu_dep ka43_calls = {
ka43_steal_pages,
- no_nicr_clock,
ka43_mchk,
ka43_memerr,
ka43_conf,
chip_clkread,
chip_clkwrite,
7, /* 7.6 VUP */
- (void*)KA43_INTREQ,
- (void*)KA43_INTCLR,
- (void*)KA43_INTMSK,
- ka43_map,
+ 2, /* SCB pages */
+ ka43_halt,
+ ka43_reboot,
+ ka43_clrf,
};
/*
* enabled. Thus we initialize these four pointers with physical addresses,
* but before leving ka43_steal_pages() we reset them to virtual addresses.
*/
-struct ka43_cpu *ka43_cpu = (void*)KA43_CPU_BASE;
-
-u_int *ka43_creg = (void*)KA43_CH2_CREG;
-u_int *ka43_ctag = (void*)KA43_CT2_BASE;
+static volatile struct ka43_cpu *ka43_cpu = (void*)KA43_CPU_BASE;
+static volatile u_int *ka43_creg = (void*)KA43_CH2_CREG;
+static volatile u_int *ka43_ctag = (void*)KA43_CT2_BASE;
#define KA43_MC_RESTART 0x00008000 /* Restart possible*/
#define KA43_PSL_FPDONE 0x00010000 /* First Part Done */
/*
* If either the Restart flag is set or the First-Part-Done flag
- * is set, and the TRAP2 (double error) bit is not set, the the
+ * is set, and the TRAP2 (double error) bit is not set, then the
* error is recoverable.
*/
if (mfpr(PR_PCSTS) & KA43_PCS_TRAP2) {
return (ka43_cache_reset());
}
-int
+#if 0
+void
ka43_clear_errors()
{
int val = *ka43_creg;
val |= KA43_SESR_SERR | KA43_SESR_LERR | KA43_SESR_CERR;
*ka43_creg = val;
}
+#endif
int
ka43_cache_reset()
printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA43_PCSTS_BITS);
printf("secondary cache status: %b\n", *ka43_creg, KA43_SESR_BITS);
- printf("cpu status: parctl=0x%x, hltcod=0x%x\n",
- ka43_cpu->parctl, ka43_cpu->hltcod);
return (0);
}
int
ka43_cache_disable()
{
- int i, val;
+ int val;
/*
* first disable primary cache and clear error flags
*/
val = 0xff;
/* if (memory > 28 MB) val = 0x55; */
- printf("clearing tags...\n");
for (i = 0; i < KA43_CT2_SIZE; i+= 4) { /* Quadword entries ?? */
ka43_ctag[i/4] = val; /* reset upper and lower */
}
}
void
-ka43_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka43_conf()
{
- extern char cpu_model[];
- extern int vax_siedata;
+ printf("cpu: KA43\n");
+ ka43_cpu = (void *)vax_map_physmem(VS_REGS, 1);
- if (vax_siedata & 0x02) /* "single-user" flag */
- strcpy(cpu_model,"VAXstation 3100 model 76");
- else if (vax_siedata & 0x01) /* "multiuser" flag */
- strcpy(cpu_model,"MicroVAX 3100 model 76(?)");
- else
- strcpy(cpu_model, "unknown KA43 board");
-
- printf(": %s\n", cpu_model);
+ ka43_creg = (void *)vax_map_physmem(KA43_CH2_CREG, 1);
+ ka43_ctag = (void *)vax_map_physmem(KA43_CT2_BASE,
+ (KA43_CT2_SIZE/VAX_NBPG));
/*
* ka43_conf() gets called with MMU enabled, now it's save to
* init/reset the caches.
*/
ka43_cache_init();
+
+ clk_adrshift = 1; /* Addressed at long's... */
+ clk_tweak = 2; /* ...and shift two */
+ clk_page = (short *)vax_map_physmem(VS_CLOCK, 1);
}
* is setup in the xxx_steal_pages() routine. We decrease highest
* available address by 64K and use this area as communication buffer.
*/
-u_long le_iomem; /* base addr of RAM -- CPU's view */
-u_long le_ioaddr; /* base addr of RAM -- LANCE's view */
void
ka43_steal_pages()
{
- extern vm_offset_t avail_start, virtual_avail, avail_end;
- extern short *clk_page;
- extern int clk_adrshift, clk_tweak;
- int junk, val;
- int i;
-
- printf ("ka43_steal_pages: avail_end=0x%x\n", avail_end);
-
- /*
- * SCB is already copied/initialized at addr avail_start
- * by pmap_bootstrap(), but it's not yet mapped. Thus we use
- * the MAPPHYS() macro to reserve these two pages and to
- * perform the mapping. The mapped address is assigned to junk.
- */
- MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE);
-
- clk_adrshift = 1; /* Addressed at long's... */
- clk_tweak = 2; /* ...and shift two */
- MAPVIRT(clk_page, 2);
- pmap_map((vm_offset_t)clk_page, (vm_offset_t)KA43_WAT_BASE,
- (vm_offset_t)KA43_WAT_BASE + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
-#if 0
- /*
- * At top of physical memory there are some console-prom and/or
- * restart-specific data. Make this area unavailable.
- */
- avail_end -= 64 * NBPG; /* scratch RAM ??? */
- avail_end = 0x00FC0000; /* XXX: for now from ">>> show mem" */
+ int val;
-This is no longer neccessary since the memsize in RPB does not include
-these unavailable pages. Only valid/available pages are counted in RPB.
-
-#endif
-
- /*
- * If we need to map physical areas also, we can decrease avail_end
- * (the highest available memory-address), copy the stuff into the
- * gap between and use pmap_map to map it. This is done for LANCE's
- * 64K communication area.
- *
- * Don't use the MAPPHYS macro here, since this uses and changes(!)
- * the value of avail_start. Use MAPVIRT even if it's name misleads.
- */
- avail_end -= (64 * 1024); /* reserve 64K */
- avail_end &= ~0xffff; /* force proper (quad?) alignment */
-
- /*
- * Oh holy shit! It took me over one year(!) to find out that
- * the 3100/76 has to use diag-mem instead of physical memory
- * for communication with LANCE (using phys-mem results in
- * parity errors and mchk exceptions with code 17 (0x11)).
- *
- * Many thanks to Matt Thomas, without his help it could have
- * been some more years... ;-)
- */
- le_ioaddr = avail_end | KA43_DIAGMEM; /* ioaddr in diag-mem!!! */
- MAPVIRT(le_iomem, (64 * 1024)/NBPG);
- pmap_map((vm_offset_t)le_iomem, le_ioaddr, le_ioaddr + 0xffff,
- VM_PROT_READ|VM_PROT_WRITE);
/*
* if LANCE\'s io-buffer is above 16 MB, then the appropriate flag
* by the RIGEL chip itself!?!
*/
val = ka43_cpu->parctl & 0x03; /* read the old value */
- if (le_ioaddr & (1 << 24)) /* if RAM above 16 MB */
- val |= KA43_PCTL_DMA; /* set LANCE DMA flag */
ka43_cpu->parctl = val; /* and write new value */
- le_ioaddr &= 0xffffff; /* Lance uses 24-bit addresses */
+}
- /*
- * now map in anything listed in ka43_map...
- */
- uvax_fillmap();
+static void
+ka43_clrf()
+{
+ struct ka43_clock *clk = (void *)clk_page;
- /*
- * Clear restart and boot in progress flags in the CPMBX.
- */
- ((struct ka43_clock *)KA43_WAT_BASE)->cpmbx =
- ((struct ka43_clock *)KA43_WAT_BASE)->cpmbx & 0xF0;
+ /*
+ * Clear restart and boot in progress flags in the CPMBX.
+ */
+ clk->cpmbx = (clk->cpmbx & ~0xf0);
+}
-#if 0
- /*
- * Clear all error flags, not really neccessary here, this will
- * be done by ka43_cache_init() anyway...
- */
- ka43_clear_errors();
-#endif
+static void
+ka43_halt()
+{
+ asm("movl $0xc, (%0)"::"r"((int)clk_page + 0x38)); /* Don't ask */
+ asm("halt");
+}
- /*
- * MM is not yet enabled, thus we still used the physical addresses,
- * but before leaving this routine, we need to reset them to virtual.
- */
- ka43_cpu = (void*)uvax_phys2virt(KA43_CPU_BASE);
- ka43_creg = (void*)uvax_phys2virt(KA43_CH2_CREG);
- ka43_ctag = (void*)uvax_phys2virt(KA43_CT2_BASE);
+static void
+ka43_reboot(arg)
+ int arg;
+{
+ asm("movl $0xc, (%0)"::"r"((int)clk_page + 0x38)); /* Don't ask */
+ asm("halt");
}
+
--- /dev/null
+/* $OpenBSD: ka46.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: ka46.c,v 1.12 2000/03/04 07:27:49 matt Exp $ */
+/*
+ * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by Bertram Barth.
+ *
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/pte.h>
+#include <machine/cpu.h>
+#include <machine/mtpr.h>
+#include <machine/sid.h>
+#include <machine/pmap.h>
+#include <machine/nexus.h>
+#include <machine/uvax.h>
+#include <machine/ka410.h>
+#include <machine/ka420.h>
+#include <machine/ka46.h>
+#include <machine/clock.h>
+#include <machine/vsbus.h>
+
+static void ka46_conf __P((void));
+static void ka46_steal_pages __P((void));
+static void ka46_memerr __P((void));
+static int ka46_mchk __P((caddr_t));
+static void ka46_halt __P((void));
+static void ka46_reboot __P((int));
+static void ka46_cache_enable __P((void));
+
+struct vs_cpu *ka46_cpu;
+
+/*
+ * Declaration of 46-specific calls.
+ */
+struct cpu_dep ka46_calls = {
+ ka46_steal_pages,
+ ka46_mchk,
+ ka46_memerr,
+ ka46_conf,
+ chip_clkread,
+ chip_clkwrite,
+ 12, /* ~VUPS */
+ 2, /* SCB pages */
+ ka46_halt,
+ ka46_reboot,
+};
+
+
+void
+ka46_conf()
+{
+ printf("cpu: KA46\n");
+ ka46_cpu = (void *)vax_map_physmem(VS_REGS, 1);
+ printf("cpu: turning on floating point chip\n");
+ mtpr(2, PR_ACCS); /* Enable floating points */
+ /*
+ * Setup parameters necessary to read time from clock chip.
+ */
+ clk_adrshift = 1; /* Addressed at long's... */
+ clk_tweak = 2; /* ...and shift two */
+ clk_page = (short *)vax_map_physmem(VS_CLOCK, 1);
+}
+
+void
+ka46_cache_enable()
+{
+ int i, *tmp;
+
+ /* Disable caches */
+ *(int *)KA46_CCR &= ~CCR_SPECIO;/* secondary */
+ mtpr(PCSTS_FLUSH, PR_PCSTS); /* primary */
+ *(int *)KA46_BWF0 &= ~BWF0_FEN; /* invalidate filter */
+
+ /* Clear caches */
+ tmp = (void *)KA46_INVFLT; /* inv filter */
+ for (i = 0; i < 32768; i++)
+ tmp[i] = 0;
+
+ /* Write valid parity to all primary cache entries */
+ for (i = 0; i < 256; i++) {
+ mtpr(i << 3, PR_PCIDX);
+ mtpr(PCTAG_PARITY, PR_PCTAG);
+ }
+
+ /* Secondary cache */
+ tmp = (void *)KA46_TAGST;
+ for (i = 0; i < KA46_TAGSZ*2; i+=2)
+ tmp[i] = 0;
+
+ /* Enable cache */
+ *(int *)KA46_BWF0 |= BWF0_FEN; /* invalidate filter */
+ mtpr(PCSTS_ENABLE, PR_PCSTS);
+ *(int *)KA46_CCR = CCR_SPECIO | CCR_CENA;
+}
+
+void
+ka46_memerr()
+{
+ printf("Memory err!\n");
+}
+
+int
+ka46_mchk(addr)
+ caddr_t addr;
+{
+ panic("Machine check");
+ return 0;
+}
+
+void
+ka46_steal_pages()
+{
+
+ /* Turn on caches (to speed up execution a bit) */
+ ka46_cache_enable();
+}
+
+static void
+ka46_halt()
+{
+ asm("halt");
+}
+
+static void
+ka46_reboot(arg)
+ int arg;
+{
+ asm("halt");
+}
--- /dev/null
+/* $OpenBSD: ka48.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/*
+ * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by Bertram Barth.
+ *
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*** needs to be completed MK-990306 ***/
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/pte.h>
+#include <machine/cpu.h>
+#include <machine/mtpr.h>
+#include <machine/sid.h>
+#include <machine/pmap.h>
+#include <machine/nexus.h>
+#include <machine/uvax.h>
+#include <machine/ka410.h>
+#include <machine/ka420.h>
+#include <machine/ka48.h>
+#include <machine/clock.h>
+#include <machine/vsbus.h>
+
+static void ka48_conf __P((void));
+static void ka48_steal_pages __P((void));
+static void ka48_memerr __P((void));
+static int ka48_mchk __P((caddr_t));
+static void ka48_halt __P((void));
+static void ka48_reboot __P((int));
+static void ka48_cache_enable __P((void));
+
+struct vs_cpu *ka48_cpu;
+
+/*
+ * Declaration of 48-specific calls.
+ */
+struct cpu_dep ka48_calls = {
+ ka48_steal_pages,
+ ka48_mchk,
+ ka48_memerr,
+ ka48_conf,
+ chip_clkread,
+ chip_clkwrite,
+ 6, /* ~VUPS */
+ 2, /* SCB pages */
+ ka48_halt,
+ ka48_reboot,
+};
+
+
+void
+ka48_conf()
+{
+ printf("cpu: KA48\n");
+ ka48_cpu = (void *)vax_map_physmem(VS_REGS, 1);
+ printf("cpu: turning on floating point chip\n");
+ mtpr(2, PR_ACCS); /* Enable floating points */
+ /*
+ * Setup parameters necessary to read time from clock chip.
+ */
+ clk_adrshift = 1; /* Addressed at long's... */
+ clk_tweak = 2; /* ...and shift two */
+ clk_page = (short *)vax_map_physmem(VS_CLOCK, 1);
+}
+
+void
+ka48_cache_enable()
+{
+ int i, *tmp;
+ return; /*** not yet MK-990306 ***/
+
+ /* Disable caches */
+ *(int *)KA48_CCR &= ~CCR_SPECIO;/* secondary */
+ mtpr(PCSTS_FLUSH, PR_PCSTS); /* primary */
+ *(int *)KA48_BWF0 &= ~BWF0_FEN; /* invalidate filter */
+
+ /* Clear caches */
+ tmp = (void *)KA48_INVFLT; /* inv filter */
+ for (i = 0; i < 32768; i++)
+ tmp[i] = 0;
+
+ /* Write valid parity to all primary cache entries */
+ for (i = 0; i < 256; i++) {
+ mtpr(i << 3, PR_PCIDX);
+ mtpr(PCTAG_PARITY, PR_PCTAG);
+ }
+
+ /* Secondary cache */
+ tmp = (void *)KA48_TAGST;
+ for (i = 0; i < KA48_TAGSZ*2; i+=2)
+ tmp[i] = 0;
+
+ /* Enable cache */
+ *(int *)KA48_BWF0 |= BWF0_FEN; /* invalidate filter */
+ mtpr(PCSTS_ENABLE, PR_PCSTS);
+ *(int *)KA48_CCR = CCR_SPECIO | CCR_CENA;
+}
+
+void
+ka48_memerr()
+{
+ printf("Memory err!\n");
+}
+
+int
+ka48_mchk(addr)
+ caddr_t addr;
+{
+ panic("Machine check");
+ return 0;
+}
+
+void
+ka48_steal_pages()
+{
+ /* Turn on caches (to speed up execution a bit) */
+ ka48_cache_enable();
+}
+
+static void
+ka48_halt()
+{
+ asm("halt");
+}
+
+static void
+ka48_reboot(arg)
+ int arg;
+{
+ asm("halt");
+}
--- /dev/null
+/* $OpenBSD: ka49.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/clock.h>
+#include <machine/cpu.h>
+#include <machine/scb.h>
+
+static void ka49_conf __P((void));
+static void ka49_memerr __P((void));
+static int ka49_mchk __P((caddr_t));
+static void ka49_halt __P((void));
+static void ka49_reboot __P((int));
+static void ka49_softmem __P((void *));
+static void ka49_hardmem __P((void *));
+static void ka49_steal_pages __P((void));
+static void ka49_cache_enable __P((void));
+static void ka49_halt __P((void));
+
+extern int cold; /* cold-start flag */
+
+/*
+ * Declaration of 49-specific calls.
+ */
+struct cpu_dep ka49_calls = {
+ ka49_steal_pages,
+ ka49_mchk,
+ ka49_memerr,
+ ka49_conf,
+ chip_clkread,
+ chip_clkwrite,
+ 16, /* ~VUPS */
+ 2, /* SCB pages */
+ ka49_halt,
+ ka49_reboot,
+};
+
+
+void
+ka49_conf()
+{
+ printf("cpu0: KA49\n");
+
+/* Why??? */
+{ volatile int *hej = (void *)mfpr(PR_ISP); *hej = *hej; hej[-1] = hej[-1];}
+
+ /*
+ * Setup parameters necessary to read time from clock chip.
+ */
+ clk_adrshift = 1; /* Addressed at long's... */
+ clk_tweak = 2; /* ...and shift two */
+ clk_page = (short *)vax_map_physmem(0x25400000, 1);
+}
+
+/*
+ * Why may we get memory errors during startup???
+ */
+void
+ka49_hardmem(arg)
+ void *arg;
+{
+ if (cold == 0)
+ printf("Hard memory error\n");
+ splhigh();
+}
+
+void
+ka49_softmem(arg)
+ void *arg;
+{
+ if (cold == 0)
+ printf("Soft memory error\n");
+ splhigh();
+}
+
+/*
+ * KA49-specific IPRs. KA49 has the funny habit to control all caches
+ * via IPRs.
+ */
+#define PR_CCTL 0xa0
+#define CCTL_ENABLE 0x00000001
+#define CCTL_SSIZE 0x00000002
+#define CCTL_VSIZE 0x00000004
+#define CCTL_SW_ETM 0x40000000
+#define CCTL_HW_ETM 0x80000000
+
+#define PR_BCETSTS 0xa3
+#define PR_BCEDSTS 0xa6
+#define PR_NESTS 0xae
+
+#define PR_VMAR 0xd0
+#define PR_VTAG 0xd1
+#define PR_ICSR 0xd3
+#define ICSR_ENABLE 0x01
+
+#define PR_PCCTL 0xf8
+#define PCCTL_P_EN 0x10
+#define PCCTL_I_EN 0x02
+#define PCCTL_D_EN 0x01
+
+void
+ka49_cache_enable()
+{
+ int start, slut;
+
+ /*
+ * Turn caches off.
+ */
+ mtpr(0, PR_ICSR);
+ mtpr(0, PR_PCCTL);
+ mtpr(mfpr(PR_CCTL) | CCTL_SW_ETM, PR_CCTL);
+
+ /*
+ * Invalidate caches.
+ */
+ mtpr(mfpr(PR_CCTL) | 0x10, PR_CCTL); /* Set cache size */
+ mtpr(mfpr(PR_BCETSTS), PR_BCETSTS); /* Clear error bits */
+ mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS); /* Clear error bits */
+ mtpr(mfpr(PR_NESTS), PR_NESTS); /* Clear error bits */
+
+
+ start = 0x01400000;
+ slut = 0x01440000;
+
+ /* Flush cache lines */
+ for (; start < slut; start += 0x20)
+ mtpr(0, start);
+
+ mtpr((mfpr(PR_CCTL) & ~(CCTL_SW_ETM|CCTL_ENABLE)) | CCTL_HW_ETM,
+ PR_CCTL);
+
+ start = 0x01000000;
+ slut = 0x01040000;
+
+ /* clear tag and valid */
+ for (; start < slut; start += 0x20)
+ mtpr(0, start);
+
+ mtpr(mfpr(PR_CCTL) | 0x10 | CCTL_ENABLE, PR_CCTL); /* enab. bcache */
+
+ start = 0x01800000;
+ slut = 0x01802000;
+
+ /* Clear primary cache */
+ for (; start < slut; start += 0x20)
+ mtpr(0, start);
+
+ /* Flush the pipes (via REI) */
+ asm("movpsl -(sp); movab 1f,-(sp); rei; 1:;");
+
+ /* Enable primary cache */
+ mtpr(PCCTL_P_EN|PCCTL_I_EN|PCCTL_D_EN, PR_PCCTL);
+
+ /* Enable the VIC */
+ start = 0;
+ slut = 0x800;
+ for (; start < slut; start += 0x20) {
+ mtpr(start, PR_VMAR);
+ mtpr(0, PR_VTAG);
+ }
+ mtpr(ICSR_ENABLE, PR_ICSR);
+}
+
+void
+ka49_memerr()
+{
+ printf("Memory err!\n");
+}
+
+int
+ka49_mchk(addr)
+ caddr_t addr;
+{
+ panic("Machine check");
+ return 0;
+}
+
+void
+ka49_steal_pages()
+{
+
+ /*
+ * Get the soft and hard memory error vectors now.
+ */
+ scb_vecalloc(0x54, ka49_softmem, 0, 0);
+ scb_vecalloc(0x60, ka49_hardmem, 0, 0);
+
+ /* Turn on caches (to speed up execution a bit) */
+ ka49_cache_enable();
+}
+
+static void
+ka49_halt()
+{
+ asm("halt");
+}
+
+static void
+ka49_reboot(arg)
+ int arg;
+{
+ asm("halt");
+}
-/* $OpenBSD: ka630.c,v 1.4 1997/09/12 09:30:55 maja Exp $ */
-/* $NetBSD: ka630.c,v 1.7 1997/07/26 10:12:46 ragge Exp $ */
+/* $OpenBSD: ka630.c,v 1.5 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka630.c,v 1.17 1999/09/06 19:52:52 ragge Exp $ */
/*-
* Copyright (c) 1982, 1988, 1990, 1993
* The Regents of the University of California. All rights reserved.
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/time.h>
+#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
-#include <machine/pte.h>
#include <machine/cpu.h>
-#include <machine/mtpr.h>
-#include <machine/sid.h>
#include <machine/pmap.h>
-#include <machine/nexus.h>
-#include <machine/uvax.h>
#include <machine/ka630.h>
#include <machine/clock.h>
-#include <vax/vax/gencons.h>
+#include <machine/vsbus.h>
static struct uvaxIIcpu *uvaxIIcpu_ptr;
-static void ka630_conf __P((struct device *, struct device *, void *));
+static void ka630_conf __P((void));
static void ka630_memerr __P((void));
static int ka630_mchk __P((caddr_t));
-static void ka630_steal_pages __P((void));
static void ka630_halt __P((void));
static void ka630_reboot __P((int));
-
-extern short *clk_page;
+static void ka630_clrf __P((void));
struct cpu_dep ka630_calls = {
- ka630_steal_pages,
- no_nicr_clock,
+ 0,
ka630_mchk,
ka630_memerr,
ka630_conf,
chip_clkread,
chip_clkwrite,
1, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0,
+ 2, /* SCB pages */
ka630_halt,
ka630_reboot,
+ ka630_clrf,
};
/*
* uvaxII_conf() is called by cpu_attach to do the cpu_specific setup.
*/
void
-ka630_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka630_conf()
{
- extern char cpu_model[];
+ clk_adrshift = 0; /* Addressed at short's... */
+ clk_tweak = 0; /* ...and no shifting */
+ clk_page = (short *)vax_map_physmem((paddr_t)KA630CLK, 1);
- strcpy(cpu_model,"MicroVAX II");
- printf(": %s\n", cpu_model);
+ uvaxIIcpu_ptr = (void *)vax_map_physmem(VS_REGS, 1);
+
+ /*
+ * Enable memory parity error detection and clear error bits.
+ */
+ uvaxIIcpu_ptr->uvaxII_mser = (UVAXIIMSER_PEN | UVAXIIMSER_MERR |
+ UVAXIIMSER_LEB);
}
/* log crd errors */
int mc63_psl; /* trapped psl */
};
+int
ka630_mchk(cmcf)
caddr_t cmcf;
{
mcf->mc63_mrvaddr, mcf->mc63_istate,
mcf->mc63_pc, mcf->mc63_psl);
if (uvaxIIcpu_ptr && uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_MERR) {
- printf("\tmser=0x%x ", uvaxIIcpu_ptr->uvaxII_mser);
+ printf("\tmser=0x%lx ", uvaxIIcpu_ptr->uvaxII_mser);
if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_CPUE)
- printf("page=%d", uvaxIIcpu_ptr->uvaxII_cear);
+ printf("page=%ld", uvaxIIcpu_ptr->uvaxII_cear);
if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_DQPE)
- printf("page=%d", uvaxIIcpu_ptr->uvaxII_dear);
+ printf("page=%ld", uvaxIIcpu_ptr->uvaxII_dear);
printf("\n");
}
return (-1);
}
-void
-ka630_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail, avail_end;
- extern int clk_adrshift, clk_tweak;
- int junk;
-
- /*
- * MicroVAX II: get 10 pages from top of memory,
- * map in Qbus map registers, cpu and clock registers.
- */
- avail_end -= 10;
-
- MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE);
- MAPVIRT(nexus, btoc(0x400000));
- pmap_map((vm_offset_t)nexus, 0x20088000, 0x20090000,
- VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(uvaxIIcpu_ptr, 1);
- pmap_map((vm_offset_t)uvaxIIcpu_ptr, (vm_offset_t)UVAXIICPU,
- (vm_offset_t)UVAXIICPU + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- clk_adrshift = 0; /* Addressed at short's... */
- clk_tweak = 0; /* ...and no shifting */
- MAPVIRT(clk_page, 1);
- pmap_map((vm_offset_t)clk_page, (vm_offset_t)KA630CLK,
- (vm_offset_t)KA630CLK + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- /*
- * Clear restart and boot in progress flags in the CPMBX.
- * Note: We are not running virtual yet.
- */
- KA630CLK->cpmbx = (KA630CLK->cpmbx & KA630CLK_LANG);
-
- /*
- * Enable memory parity error detection and clear error bits.
- */
- UVAXIICPU->uvaxII_mser = (UVAXIIMSER_PEN | UVAXIIMSER_MERR |
- UVAXIIMSER_LEB);
-}
-
static void
ka630_halt()
{
{
((struct ka630clock *)clk_page)->cpmbx =
KA630CLK_DOTHIS | KA630CLK_REBOOT;
- mtpr(GC_BOOT, PR_TXDB);
- asm("movl %0,r5;halt"::"g"(arg));
+}
+
+/*
+ * Clear restart and boot in progress flags in the CPMBX.
+ */
+static void
+ka630_clrf()
+{
+ short i = ((struct ka630clock *)clk_page)->cpmbx;
+
+ ((struct ka630clock *)clk_page)->cpmbx = i & KA630CLK_LANG;
}
-/* $OpenBSD: ka650.c,v 1.6 1997/09/12 09:30:55 maja Exp $ */
-/* $NetBSD: ka650.c,v 1.10 1997/07/26 10:12:48 ragge Exp $ */
+/* $OpenBSD: ka650.c,v 1.7 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka650.c,v 1.20 1999/08/07 10:36:49 ragge Exp $ */
/*
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/mtpr.h>
-#include <machine/nexus.h>
#include <machine/sid.h>
-#include <vax/vax/gencons.h>
-
struct ka650_merr *ka650merr_ptr;
struct ka650_cbd *ka650cbd_ptr;
struct ka650_ssc *ka650ssc_ptr;
struct ka650_ipcr *ka650ipcr_ptr;
int *KA650_CACHE_ptr;
-static int subtyp;
#define CACHEOFF 0
#define CACHEON 1
-void ka650setcache __P((int));
-static void ka650_halt __P((void));
-static void ka650_reboot __P((int));
+static void ka650setcache __P((int));
+static void ka650_halt __P((void));
+static void ka650_reboot __P((int));
+static void uvaxIII_conf __P((void));
+static void uvaxIII_memerr __P((void));
+static int uvaxIII_mchk __P((caddr_t));
struct cpu_dep ka650_calls = {
- uvaxIII_steal_pages,
- no_nicr_clock,
+ 0, /* No special page stealing anymore */
uvaxIII_mchk,
uvaxIII_memerr,
uvaxIII_conf,
generic_clkread,
generic_clkwrite,
4, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0,
+ 2, /* SCB pages */
ka650_halt,
ka650_reboot,
};
* uvaxIII_conf() is called by cpu_attach to do the cpu_specific setup.
*/
void
-uvaxIII_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+uvaxIII_conf()
{
- extern char cpu_model[];
- int syssub = GETSYSSUBT(subtyp);
- char *str;
+ int syssub = GETSYSSUBT(vax_siedata);
/*
- * There are lots of different MicroVAX III models, we should
- * check which hereas there are some differences in the setup code
- * that depends on this.
+ * MicroVAX III: We map in memory error registers,
+ * cache control registers, SSC registers,
+ * interprocessor registers and cache diag space.
*/
- strcpy(cpu_model,"MicroVAX ");
- switch (syssub) {
- case VAX_SIE_KA640:
- str = "3300/3400";
- break;
-
- case VAX_SIE_KA650:
- str = "3500/3600";
- break;
-
- case VAX_SIE_KA655:
- str = "3800/3900";
- break;
-
- default:
- str = "III";
- break;
- }
- strcat(cpu_model, str);
- printf(": %s\n",cpu_model);
- printf("%s: CVAX microcode rev %d Firmware rev %d\n", self->dv_xname,
- (vax_cpudata & 0xff), GETFRMREV(subtyp));
- ka650setcache(CACHEON);
+ ka650merr_ptr = (void *)vax_map_physmem(KA650_MERR, 1);
+ ka650cbd_ptr = (void *)vax_map_physmem(KA650_CBD, 1);
+ ka650ssc_ptr = (void *)vax_map_physmem(KA650_SSC, 3);
+ ka650ipcr_ptr = (void *)vax_map_physmem(KA650_IPCR, 1);
+ KA650_CACHE_ptr = (void *)vax_map_physmem(KA650_CACHE,
+ (KA650_CACHESIZE/VAX_NBPG));
+
+ printf("cpu: KA6%d%d, CVAX microcode rev %d Firmware rev %d\n",
+ syssub == VAX_SIE_KA640 ? 4 : 5,
+ syssub == VAX_SIE_KA655 ? 5 : 0,
+ (vax_cpudata & 0xff), GETFRMREV(vax_siedata));
+ if (syssub != VAX_SIE_KA640)
+ ka650setcache(CACHEON);
if (ctob(physmem) > ka650merr_ptr->merr_qbmbr) {
printf("physmem(0x%x) > qbmbr(0x%x)\n",
ctob(physmem), (int)ka650merr_ptr->merr_qbmbr);
panic("qbus map unprotected");
}
-}
-
-void
-uvaxIII_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail, avail_end;
- int junk, *jon;
-
- /*
- * MicroVAX III: We steal away 64 pages from top of memory,
- * map in SCB, interrupt vectors, Qbus map registers, memory
- * error registers, cache control registers, SSC registers,
- * interprocessor registers and cache diag space.
- */
- avail_end -= 64 * NBPG;
-
- MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE); /* SCB & vectors */
- MAPVIRT(nexus, btoc(0x400000)); /* Qbus map registers */
- pmap_map((vm_offset_t)nexus, 0x20088000, 0x20090000,
- VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(ka650merr_ptr, 1); /* mem err & mem config regs */
- pmap_map((vm_offset_t)ka650merr_ptr, (vm_offset_t)KA650_MERR,
- KA650_MERR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(ka650cbd_ptr, 1); /* cache control & boot/diag regs */
- pmap_map((vm_offset_t)ka650cbd_ptr, (vm_offset_t)KA650_CBD,
- KA650_CBD + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(ka650ssc_ptr, 3); /* SSC regs (& console prog mail box) */
- pmap_map((vm_offset_t)ka650ssc_ptr, (vm_offset_t)KA650_SSC,
- KA650_SSC + NBPG * 3, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(ka650ipcr_ptr, 1); /* InterProcessor Com Regs */
- pmap_map((vm_offset_t)ka650ipcr_ptr, (vm_offset_t)KA650_IPCR,
- KA650_IPCR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(KA650_CACHE_ptr, 128); /* Cache Diagnostic space (for flush) */
- pmap_map((vm_offset_t)KA650_CACHE_ptr, (vm_offset_t)KA650_CACHE,
- KA650_CACHE + KA650_CACHESIZE, VM_PROT_READ|VM_PROT_WRITE);
-
- jon = (int *)0x20040004;
- subtyp = *jon;
+ if (mfpr(PR_TODR) == 0)
+ mtpr(1, PR_TODR);
}
void
int arg;
{
ka650ssc_ptr->ssc_cpmbx = CPMB650_DOTHIS | CPMB650_REBOOT;
- mtpr(GC_BOOT, PR_TXDB);
- asm("movl %0,r5;halt"::"g"(arg));
}
-
--- /dev/null
+/* $OpenBSD: ka670.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: ka670.c,v 1.4 2000/03/13 23:52:35 soren Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by Bertram Barth.
+ *
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
+#include <machine/pte.h>
+#include <machine/cpu.h>
+#include <machine/mtpr.h>
+#include <machine/sid.h>
+#include <machine/pmap.h>
+#include <machine/nexus.h>
+#include <machine/uvax.h>
+#include <machine/vsbus.h>
+#include <machine/ka670.h>
+#include <machine/clock.h>
+
+static void ka670_conf __P((void));
+
+static int ka670_mchk __P((caddr_t));
+static void ka670_memerr __P((void));
+static int ka670_cache_init __P((void)); /* "int mapen" as argument? */
+static void ka670_halt __P((void));
+static void ka670_reboot __P((int));
+
+struct cpu_dep ka670_calls = {
+ 0,
+ ka670_mchk,
+ ka670_memerr,
+ ka670_conf,
+ generic_clkread,
+ generic_clkwrite,
+ 8, /* 8 VUP */
+ 2, /* SCB pages */
+ ka670_halt,
+ ka670_reboot,
+ 0,
+};
+
+#define KA670_MC_RESTART 0x00008000 /* Restart possible*/
+#define KA670_PSL_FPDONE 0x00010000 /* First Part Done */
+
+struct ka670_mcframe { /* Format of RigelMAX machine check frame: */
+ int mc670_bcnt; /* byte count, always 24 (0x18) */
+ int mc670_code; /* machine check type code and restart bit */
+ int mc670_addr; /* most recent (faulting?) virtual address */
+ int mc670_viba; /* contents of VIBA register */
+ int mc670_sisr; /* ICCS bit 6 and SISR bits 15:0 */
+ int mc670_istate; /* internal state */
+ int mc670_sc; /* shift count register */
+ int mc670_pc; /* trapped PC */
+ int mc670_psl; /* trapped PSL */
+};
+
+#if 0
+
+/*
+ * This is not the mchk types on KA670.
+ */
+static char *ka670_mctype[] = {
+ "no error (0)", /* Code 0: No error */
+ "FPA: protocol error", /* Code 1-5: FPA errors */
+ "FPA: illegal opcode",
+ "FPA: operand parity error",
+ "FPA: unknown status",
+ "FPA: result parity error",
+ "unused (6)", /* Code 6-7: Unused */
+ "unused (7)",
+ "MMU error (TLB miss)", /* Code 8-9: MMU errors */
+ "MMU error (TLB hit)",
+ "HW interrupt at unused IPL", /* Code 10: Interrupt error */
+ "MOVCx impossible state", /* Code 11-13: Microcode errors */
+ "undefined trap code (i-box)",
+ "undefined control store address",
+ "unused (14)", /* Code 14-15: Unused */
+ "unused (15)",
+ "PC tag or data parity error", /* Code 16: Cache error */
+ "data bus parity error", /* Code 17: Read error */
+ "data bus error (NXM)", /* Code 18: Write error */
+ "undefined data bus state", /* Code 19: Bus error */
+};
+#define MC670_MAX 19
+#endif
+
+static int ka670_error_count = 0;
+
+int
+ka670_mchk(addr)
+ caddr_t addr;
+{
+ register struct ka670_mcframe *mcf = (void*)addr;
+
+ mtpr(0x00, PR_MCESR); /* Acknowledge the machine check */
+ printf("machine check %d (0x%x)\n", mcf->mc670_code, mcf->mc670_code);
+ printf("PC %x PSL %x\n", mcf->mc670_pc, mcf->mc670_psl);
+ if (++ka670_error_count > 10) {
+ printf("error_count exceeded: %d\n", ka670_error_count);
+ return (-1);
+ }
+
+ /*
+ * If either the Restart flag is set or the First-Part-Done flag
+ * is set, and the TRAP2 (double error) bit is not set, then the
+ * error is recoverable.
+ */
+ if (mfpr(PR_PCSTS) & KA670_PCS_TRAP2) {
+ printf("TRAP2 (double error) in ka670_mchk.\n");
+ panic("unrecoverable state in ka670_mchk.\n");
+ return (-1);
+ }
+ if ((mcf->mc670_code & KA670_MC_RESTART) ||
+ (mcf->mc670_psl & KA670_PSL_FPDONE)) {
+ printf("ka670_mchk: recovering from machine-check.\n");
+ ka670_cache_init(); /* reset caches */
+ return (0); /* go on; */
+ }
+
+ /*
+ * Unknown error state, panic/halt the machine!
+ */
+ printf("ka670_mchk: unknown error state!\n");
+ return (-1);
+}
+
+void
+ka670_memerr()
+{
+ /*
+ * Don\'t know what to do here. So just print some messages
+ * and try to go on...
+ */
+ printf("memory error!\n");
+ printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA670_PCSTS_BITS);
+ printf("secondary cache status: %b\n", mfpr(PR_BCSTS), KA670_BCSTS_BITS);
+}
+
+int
+ka670_cache_init()
+{
+ int val;
+
+ mtpr(KA670_PCS_REFRESH, PR_PCSTS); /* disable primary cache */
+ val = mfpr(PR_PCSTS);
+ mtpr(val, PR_PCSTS); /* clear error flags */
+ mtpr(8, PR_BCCTL); /* disable backup cache */
+ mtpr(0, PR_BCFBTS); /* flush backup cache tag store */
+ mtpr(0, PR_BCFPTS); /* flush primary cache tag store */
+ mtpr(0x0e, PR_BCCTL); /* enable backup cache */
+ mtpr(KA670_PCS_FLUSH | KA670_PCS_REFRESH, PR_PCSTS); /* flush primary cache */
+ mtpr(KA670_PCS_ENABLE | KA670_PCS_REFRESH, PR_PCSTS); /* flush primary cache */
+
+#ifdef DEBUG
+ printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA670_PCSTS_BITS);
+ printf("secondary cache status: %b\n", mfpr(PR_BCSTS), KA670_BCSTS_BITS);
+#endif
+
+ return (0);
+}
+void
+ka670_conf()
+{
+ printf("cpu0: KA670, ucode rev %d\n", vax_cpudata % 0377);
+
+ /*
+ * ka670_conf() gets called with MMU enabled, now it's save to
+ * init/reset the caches.
+ */
+ ka670_cache_init();
+}
+
+static void
+ka670_halt()
+{
+ asm("halt");
+}
+
+static void
+ka670_reboot(arg)
+ int arg;
+{
+ asm("halt");
+}
+
-/* $OpenBSD: ka750.c,v 1.7 1997/09/10 12:04:48 maja Exp $ */
-/* $NetBSD: ka750.c,v 1.18 1997/02/19 10:04:17 ragge Exp $ */
+/* $OpenBSD: ka750.c,v 1.8 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka750.c,v 1.30 1999/08/14 11:30:48 ragge Exp $ */
/*
* Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
*/
#include <sys/param.h>
-#include <sys/types.h>
#include <sys/device.h>
#include <sys/systm.h>
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-
#include <machine/ka750.h>
-#include <machine/clock.h>
-#include <machine/pte.h>
+#include <machine/mtpr.h>
#include <machine/cpu.h>
+#include <machine/clock.h>
#include <machine/sid.h>
-#include <machine/mtpr.h>
-#include <machine/scb.h>
-#include <vax/uba/ubavar.h>
-#include <vax/uba/ubareg.h>
+#include <vax/vax/gencons.h>
void ctuattach __P((void));
+static void ka750_clrf __P((void));
+static void ka750_conf __P((void));
+static void ka750_memerr __P((void));
+static int ka750_mchk __P((caddr_t));
-struct cpu_dep ka750_calls = {
- ka750_steal_pages,
- generic_clock,
+
+struct cpu_dep ka750_calls = {
+ 0,
ka750_mchk,
ka750_memerr,
ka750_conf,
generic_clkread,
generic_clkwrite,
- 1, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
-
+ 1, /* ~VUPS */
+ 4, /* SCB pages */
+ 0, /* halt call */
+ 0, /* Reboot call */
+ ka750_clrf,
};
-/*
- * ka750_conf() is called by cpu_attach to do the cpu_specific setup.
- */
+static caddr_t mcraddr[4]; /* XXX */
+
void
-ka750_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka750_conf()
{
- extern char cpu_model[];
-
- strcpy(cpu_model,"VAX 11/750");
- printf(": 11/750, hardware rev %d, ucode rev %d\n",
+ printf("cpu0: KA750, hardware rev %d, ucode rev %d, ",
V750HARDW(vax_cpudata), V750UCODE(vax_cpudata));
- printf("%s: ", self->dv_xname);
if (mfpr(PR_ACCS) & 255) {
printf("FPA present, enabling.\n");
mtpr(0x8000, PR_ACCS);
} else
printf("no FPA\n");
+ if (mfpr(PR_TODR) == 0) { /* Check for failing battery */
+ mtpr(1, PR_TODR);
+ printf("WARNING: TODR battery broken\n");
+ }
+
/* Call ctuattach() here so it can setup its vectors. */
ctuattach();
}
-int ka750_memmatch __P((struct device *, void *, void *));
-void ka750_memenable __P((struct device *, struct device *, void *));
+int ka750_memmatch __P((struct device *, struct cfdata *, void *));
+void ka750_memenable __P((struct device *, struct device *, void *));
-struct cfattach mem_cmi_ca = {
- sizeof(struct device), ka750_memmatch, ka750_memenable
+struct cfattach mem_cmi_ca = {
+ sizeof(struct device), ka750_memmatch, ka750_memenable
};
int
-ka750_memmatch(parent, gcf, aux)
- struct device *parent;
- void *gcf, *aux;
+ka750_memmatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
{
- struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
- struct cfdata *cf = gcf;
+ struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
- if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1))
- return 0;
+ if (cf->cf_loc[CMICF_TR] != sa->nexnum && cf->cf_loc[CMICF_TR] > -1)
+ return 0;
if (sa->type != NEX_MEM16)
return 0;
return 1;
}
-extern volatile caddr_t mcraddr[];
-
struct mcr750 {
int mc_err; /* error bits */
int mc_inh; /* inhibit crd */
/* enable crd interrupts */
void
ka750_memenable(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ struct device *parent, *self;
+ void *aux;
{
- struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
+ struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
struct mcr750 *mcr = (struct mcr750 *)sa->nexaddr;
int k, l, m, cardinfo;
}
void
-ka750_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail;
- int junk;
-
- /*
- * We take away the pages we need, one for SCB and the rest
- * for UBA vectors == 1 + 2 will alloc all needed space.
- * We also set up virtual area for SBI.
- */
- MAPPHYS(junk, V750PGS, VM_PROT_READ|VM_PROT_WRITE);
- MAPVIRT(nexus, btoc(NEX750SZ));
- pmap_map((vm_offset_t)nexus, NEX750, NEX750 + NEX750SZ,
- VM_PROT_READ|VM_PROT_WRITE);
-}
-
-static int cmi_print __P((void *, const char *));
-static int cmi_match __P((struct device *, void *, void *));
-static void cmi_attach __P((struct device *, struct device *, void*));
-
-struct cfdriver cmi_cd = {
- NULL, "cmi", DV_DULL
-};
-
-struct cfattach cmi_ca = {
- sizeof(struct device), cmi_match, cmi_attach
-};
-
-int
-cmi_print(aux, name)
- void *aux;
- const char *name;
-{
- struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
-
- if (name)
- printf("unknown device 0x%x at %s", sa->type, name);
-
- printf(" tr%d", sa->nexnum);
- return (UNCONF);
-}
-
-
-int
-cmi_match(parent, cf, aux)
- struct device *parent;
- void *cf, *aux;
+ka750_clrf()
{
- struct bp_conf *bp = aux;
+ int s = splhigh();
- if (strcmp(bp->type, "cmi"))
- return 0;
- return 1;
-}
+#define WAIT while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
-void
-cmi_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- u_int nexnum, maxnex, minnex;
- struct sbi_attach_args sa;
-
- printf("I\n");
- /*
- * Probe for memory, can be in the first 4 slots.
- */
- for (sa.nexnum = 0; sa.nexnum < 4; sa.nexnum++) {
- if (badaddr((caddr_t)&nexus[sa.nexnum], 4))
- continue;
-
- sa.nexaddr = nexus + sa.nexnum;
- sa.type = NEX_MEM16;
- config_found(self, (void*)&sa, cmi_print);
- }
+ WAIT;
- /*
- * Probe for mba's, can be in slot 4 - 7.
- */
- for (sa.nexnum = 4; sa.nexnum < 7; sa.nexnum++) {
- if (badaddr((caddr_t)&nexus[sa.nexnum], 4))
- continue;
-
- sa.nexaddr = nexus + sa.nexnum;
- sa.type = NEX_MBA;
- config_found(self, (void*)&sa, cmi_print);
- }
+ mtpr(GC_CWFL|GC_CONS, PR_TXDB);
- /*
- * There are always one generic UBA, and maybe an optional.
- */
- sa.nexnum = 8;
- sa.nexaddr = nexus + sa.nexnum;
- sa.type = NEX_UBA0;
- config_found(self, (void*)&sa, cmi_print);
- sa.type = NEX_UBA1;
- if (badaddr((caddr_t)&nexus[++sa.nexnum], 4) == 0)
- config_found(self, (void*)&sa, cmi_print);
+ WAIT;
+ mtpr(GC_CCFL|GC_CONS, PR_TXDB);
+ WAIT;
+ splx(s);
}
-/* $OpenBSD: ka780.c,v 1.4 1997/09/10 12:04:48 maja Exp $ */
-/* $NetBSD: ka780.c,v 1.7 1997/02/19 10:04:18 ragge Exp $ */
+/* $OpenBSD: ka780.c,v 1.5 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka780.c,v 1.14 1999/08/07 10:36:49 ragge Exp $ */
/*-
* Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
* All rights reserved.
*/
#include <sys/param.h>
-#include <sys/types.h>
#include <sys/device.h>
#include <sys/systm.h>
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-
-#include <machine/pte.h>
-#include <machine/clock.h>
-#include <machine/cpu.h>
-#include <machine/mtpr.h>
-#include <machine/scb.h>
#include <machine/nexus.h>
#include <machine/sid.h>
+#include <machine/cpu.h>
+#include <machine/clock.h>
-#include <vax/uba/ubavar.h>
-#include <vax/uba/ubareg.h>
-
-static void ka780_conf __P((struct device *, struct device *, void *));
-void ka780_memenable __P((struct sbi_attach_args *, void *));
static void ka780_memerr __P((void));
static int ka780_mchk __P((caddr_t));
-static void ka780_steal_pages __P((void));
+static void ka780_conf __P((void));
+static int mem_sbi_match __P((struct device *, struct cfdata *, void *));
+static void mem_sbi_attach __P((struct device *, struct device *, void*));
+
+struct cfattach mem_sbi_ca = {
+ sizeof(struct mem_softc), mem_sbi_match, mem_sbi_attach
+};
+
+int
+mem_sbi_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
+
+ if (cf->cf_loc[SBICF_TR] != sa->nexnum && cf->cf_loc[SBICF_TR] > -1)
+ return 0;
+
+ switch (sa->type) {
+ case NEX_MEM4:
+ case NEX_MEM4I:
+ case NEX_MEM16:
+ case NEX_MEM16I:
+ sa->nexinfo = M780C;
+ break;
+
+ case NEX_MEM64I:
+ case NEX_MEM64L:
+ case NEX_MEM64LI:
+ case NEX_MEM256I:
+ case NEX_MEM256L:
+ case NEX_MEM256LI:
+ sa->nexinfo = M780EL;
+ break;
+
+ case NEX_MEM64U:
+ case NEX_MEM64UI:
+ case NEX_MEM256U:
+ case NEX_MEM256UI:
+ sa->nexinfo = M780EU;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
/*
* Declaration of 780-specific calls.
*/
struct cpu_dep ka780_calls = {
- ka780_steal_pages,
- generic_clock,
+ 0,
ka780_mchk,
ka780_memerr,
ka780_conf,
generic_clkread,
generic_clkwrite,
2, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
+ 5, /* SCB pages */
};
/*
/* enable crd interrrupts */
void
-ka780_memenable(sa, osc)
- struct sbi_attach_args *sa;
- void *osc;
+mem_sbi_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
{
- struct mem_softc *sc = osc;
- register struct mcr780 *mcr = (void *)sc->sc_memaddr;
+ struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
+ struct mem_softc *sc = (void *)self;
+ struct mcr780 *mcr = (void *)sa->nexaddr;
+
+ sc->sc_memaddr = sa->nexaddr;
+ sc->sc_memtype = sa->nexinfo;
+ sc->sc_memnr = sa->type;
printf(": ");
switch (sc->sc_memtype) {
void
ka780_memerr()
{
- extern struct cfdriver mem_cd;
+ extern struct cfdriver mem_cd;
struct mem_softc *sc;
register struct mcr780 *mcr;
register int m;
};
void
-ka780_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka780_conf()
{
extern char cpu_model[];
struct ka78x *ka78 = (void *)&vax_cpudata;
/* Enable cache */
mtpr(0x200000, PR_SBIMT);
- strcpy(cpu_model,"VAX 11/780");
- if (ka78->v785)
- cpu_model[9] = '5';
- printf(": %s, serial number %d(%d), hardware ECO level %d(%d)\n",
+ printf("cpu: %s, serial number %d(%d), hardware ECO level %d(%d)\n",
&cpu_model[4], ka78->snr, ka78->plant, ka78->eco >> 4, ka78->eco);
- printf("%s: ", self->dv_xname);
if (mfpr(PR_ACCS) & 255) {
- printf("FPA present, enabling.\n");
+ printf("cpu: FPA present, enabling.\n");
mtpr(0x8000, PR_ACCS);
} else
- printf("no FPA\n");
+ printf("cpu: no FPA\n");
}
-
-void
-ka780_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail;
- extern struct nexus *nexus;
- int junk;
-
- MAPPHYS(junk, 4, VM_PROT_READ|VM_PROT_WRITE);
- MAPVIRT(nexus, btoc(8192*16));
- pmap_map((vm_offset_t)nexus, 0x20000000, 0x20020000,
- VM_PROT_READ|VM_PROT_WRITE);
-}
-/* $OpenBSD: ka820.c,v 1.3 1997/09/10 12:04:49 maja Exp $ */
-/* $NetBSD: ka820.c,v 1.5 1997/04/18 18:49:34 ragge Exp $ */
+/* $OpenBSD: ka820.c,v 1.4 2000/04/27 01:10:12 bjc Exp $ */
+/* $NetBSD: ka820.c,v 1.17 1999/09/06 19:52:52 ragge Exp $ */
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/device.h>
+#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/nexus.h>
#include <machine/clock.h>
#include <machine/scb.h>
+#include <machine/bus.h>
-#include <arch/vax/bi/bireg.h>
-#include <arch/vax/bi/bivar.h>
+#include <vax/bi/bireg.h>
+#include <vax/bi/bivar.h>
+
+#include <vax/vax/crx.h>
struct ka820port *ka820port_ptr;
struct rx50device *rx50device_ptr;
-void *bi_nodebase; /* virtual base address for all possible bi nodes */
-static int ka820_match __P((struct device *, void *, void *));
-static void ka820_attach __P((struct device *, struct device *, void*));
+static int ka820_match __P((struct device *, struct cfdata *, void *));
+static void ka820_attach __P((struct device *, struct device *, void*));
+static void rxcdintr __P((int));
+void crxintr __P((int));
struct cpu_dep ka820_calls = {
- ka820_steal_pages,
- generic_clock,
+ 0,
ka820_mchk,
ka820_memerr,
NULL,
chip_clkread,
chip_clkwrite,
3, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
-
+ 5, /* SCB pages */
};
struct cfattach cpu_bi_ca = {
#ifdef notyet
extern struct pte BRAMmap[];
extern struct pte EEPROMmap[];
-char bootram[KA820_BRPAGES * NBPG];
-char eeprom[KA820_EEPAGES * NBPG];
+char bootram[KA820_BRPAGES * VAX_NBPG];
+char eeprom[KA820_EEPAGES * VAX_NBPG];
#endif
-struct ivec_dsp nollhanterare;
-
-static void
-hant(arg)
- int arg;
-{
- if (cold == 0)
- printf("stray interrupt from vaxbi bus\n");
-}
-
-void
-ka820_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail, avail_end;
- extern struct ivec_dsp idsptch;
- extern short *clk_page;
- extern int clk_adrshift, clk_tweak;
- struct scb *sb;
- int junk, i, j;
-
- /*
- * On the ka820, we map in the port CSR, the clock registers
- * and the console RX50 register. We also map in the BI nodespace
- * for all possible (16) nodes. It would only be needed with
- * the existent nodes, but we only loose 1K so...
- */
- sb = (void *)avail_start;
- MAPPHYS(junk, j, VM_PROT_READ|VM_PROT_WRITE); /* SCB & vectors */
- clk_adrshift = 0; /* clk regs are addressed at short's */
- clk_tweak = 1; /* ...but not exactly in each short */
- MAPVIRT(clk_page, 1);
- pmap_map((vm_offset_t)clk_page, (vm_offset_t)KA820_CLOCKADDR,
- KA820_CLOCKADDR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(ka820port_ptr, 1);
- pmap_map((vm_offset_t)ka820port_ptr, (vm_offset_t)KA820_PORTADDR,
- KA820_PORTADDR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(rx50device_ptr, 1);
- pmap_map((vm_offset_t)rx50device_ptr, (vm_offset_t)KA820_RX50ADDR,
- KA820_RX50ADDR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
-
- MAPVIRT(bi_nodebase, NNODEBI * (sizeof(struct bi_node) / NBPG));
- pmap_map((vm_offset_t)bi_nodebase, (vm_offset_t)BI_BASE(0),
- BI_BASE(0) + sizeof(struct bi_node) * NNODEBI,
- VM_PROT_READ|VM_PROT_WRITE);
- bcopy(&idsptch, &nollhanterare, sizeof(struct ivec_dsp));
- nollhanterare.hoppaddr = hant;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 16; j++)
- sb->scb_nexvec[i][j] = &nollhanterare;
-
-}
-
int
-ka820_match(parent, match, aux)
+ka820_match(parent, cf, aux)
struct device *parent;
- void *match, *aux;
+ struct cfdata *cf;
+ void *aux;
{
- struct cfdata *cf = match;
struct bi_attach_args *ba = aux;
- if (ba->ba_node->biic.bi_dtype != BIDT_KA820)
+ if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_KA820)
return 0;
if (ba->ba_nodenr != mastercpu)
return 0;
- if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ba->ba_nodenr)
+ if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
+ cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
return 0;
return 1;
{
struct bi_attach_args *ba = aux;
register int csr;
- u_short rev = ba->ba_node->biic.bi_revs;
+ u_short rev;
extern char cpu_model[];
+ rev = bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) >> 16;
strcpy(cpu_model,"VAX 8200");
cpu_model[6] = rev & 0x8000 ? '5' : '0';
printf(": ka82%c (%s) cpu rev %d, u patch rev %d, sec patch %d\n",
csr |= KA820PORT_CONSCLR | KA820PORT_CRDCLR | KA820PORT_CONSEN |
KA820PORT_RXIE;
ka820port_ptr->csr = csr;
- ba->ba_node->biic.bi_intrdes = ba->ba_intcpu;
- ba->ba_node->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
+ bus_space_write_4(ba->ba_iot, ba->ba_ioh,
+ BIREG_INTRDES, ba->ba_intcpu);
+ bus_space_write_4(ba->ba_iot, ba->ba_ioh, BIREG_VAXBICSR,
+ bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_VAXBICSR) |
+ BICSR_SEIE | BICSR_HEIE);
+
+ /* XXX - should be done somewhere else */
+ scb_vecalloc(SCB_RX50, crxintr, 0, SCB_ISTACK);
+
+ clk_adrshift = 0; /* clk regs are addressed at short's */
+ clk_tweak = 1; /* ...but not exactly in each short */
+ clk_page = (short *)vax_map_physmem((paddr_t)KA820_CLOCKADDR, 1);
+
+ /* Steal the interrupt vectors that are unique for us */
+ scb_vecalloc(KA820_INT_RXCD, rxcdintr, 0, SCB_ISTACK);
+
+ rx50device_ptr = (void *)vax_map_physmem(KA820_RX50ADDR, 1);
+ ka820port_ptr = (void *)vax_map_physmem(KA820_PORTADDR, 1);
}
+#ifdef notdef
/*
* MS820 support.
*/
int ms_csr1; /* control/status register 1 */
int ms_csr2; /* control/status register 2 */
};
+#endif
+
+#define MEMRD(reg) bus_space_read_4(sc->sc_iot, sc->sc_ioh, (reg))
+#define MEMWR(reg, val) bus_space_write_4(sc->sc_iot, sc->sc_ioh, (reg), (val))
+#define MSREG_CSR1 0x100
+#define MSREG_CSR2 0x104
/*
* Bits in CSR1.
*/
#define MS2_INTLVADDR 0x00000100 /* error was in bank 1 (ro) */
#define MS2_SYN 0x0000007f /* error syndrome (ro, rw diag) */
-static int ms820_match __P((struct device *, void *, void *));
+static int ms820_match __P((struct device *, struct cfdata *, void *));
static void ms820_attach __P((struct device *, struct device *, void*));
struct mem_bi_softc {
- struct device mem_dev;
- struct ms820regs *mem_regs;
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
};
struct cfattach mem_bi_ca = {
};
static int
-ms820_match(parent, match, aux)
+ms820_match(parent, cf, aux)
struct device *parent;
- void *match, *aux;
+ struct cfdata *cf;
+ void *aux;
{
- struct cfdata *cf = match;
struct bi_attach_args *ba = aux;
- if (ba->ba_node->biic.bi_dtype != BIDT_MS820)
+ if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_MS820)
return 0;
- if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ba->ba_nodenr)
+ if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
+ cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
return 0;
return 1;
struct device *parent, *self;
void *aux;
{
- struct mem_bi_softc *ms = (void *)self;
+ struct mem_bi_softc *sc = (void *)self;
struct bi_attach_args *ba = aux;
- ms->mem_regs = (void *)ba->ba_node;
+ sc->sc_iot = ba->ba_iot;
+ sc->sc_ioh = ba->ba_ioh;
- if ((ms->mem_regs->biic.bi_csr & BICSR_STS) == 0)
+ if ((MEMRD(BIREG_VAXBICSR) & BICSR_STS) == 0)
printf(": failed self test\n");
else
- printf(": size %dMB, %s chips\n", ((ms->mem_regs->ms_csr1 &
- MS1_MSIZEMASK) >> 20), (ms->mem_regs->ms_csr1&MS1_RAMTYMASK
- ?ms->mem_regs->ms_csr1 & MS1_RAMTY256K?"256K":"1M":"64K"));
+ printf(": size %dMB, %s chips\n", ((MEMRD(MSREG_CSR1) &
+ MS1_MSIZEMASK) >> 20), (MEMRD(MSREG_CSR1) & MS1_RAMTYMASK
+ ? MEMRD(MSREG_CSR1) & MS1_RAMTY256K ? "256K":"1M":"64K"));
- ms->mem_regs->biic.bi_intrdes = ba->ba_intcpu;
- ms->mem_regs->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
+ MEMWR(BIREG_INTRDES, ba->ba_intcpu);
+ MEMWR(BIREG_VAXBICSR, MEMRD(BIREG_VAXBICSR) | BICSR_SEIE | BICSR_HEIE);
- ms->mem_regs->ms_csr1 = MS1_MWRITEERR | MS1_CNTLERR;
- ms->mem_regs->ms_csr2 = MS2_RDSERR | MS2_HIERR |
- MS2_CRDERR | MS2_ADRSERR;
+ MEMWR(MSREG_CSR1, MS1_MWRITEERR | MS1_CNTLERR);
+ MEMWR(MSREG_CSR2, MS2_RDSERR | MS2_HIERR | MS2_CRDERR | MS2_ADRSERR);
}
void
ka820_memerr()
{
- register struct ms820regs *mcr;
- struct mem_bi_softc *mc;
- extern struct cfdriver mem_cd;
- register int m, hard;
- register char *type;
+ struct mem_bi_softc *sc;
+ int m, hard, csr1, csr2;
+ char *type;
static char b1[] = "\20\40ERRSUM\37ECCDIAG\36ECCDISABLE\20CRDINH\17VALID\
\16INTLK\15BROKE\13MWRITEERR\12CNTLERR\11INTLV";
static char b2[] = "\20\40RDS\37HIERR\36CRD\35ADRS";
for (m = 0; m < mem_cd.cd_ndevs; m++) {
- mc = mem_cd.cd_devs[m];
- if (mc == NULL)
+ sc = mem_cd.cd_devs[m];
+ if (sc == NULL)
continue;
- mcr = mc->mem_regs;
- printf("%s: csr1=%b csr2=%b\n", mc->mem_dev.dv_xname,
- mcr->ms_csr1, b1, mcr->ms_csr2, b2);
- if ((mcr->ms_csr1 & MS1_ERRSUM) == 0)
+ csr1 = MEMRD(MSREG_CSR1);
+ csr2 = MEMRD(MSREG_CSR2);
+ printf("%s: csr1=%b csr2=%b\n", sc->sc_dev.dv_xname,
+ csr1, b1, csr2, b2);
+ if ((csr1 & MS1_ERRSUM) == 0)
continue;
hard = 1;
- if (mcr->ms_csr1 & MS1_BROKE)
+ if (csr1 & MS1_BROKE)
type = "broke";
- else if (mcr->ms_csr1 & MS1_CNTLERR)
+ else if (csr1 & MS1_CNTLERR)
type = "cntl err";
- else if (mcr->ms_csr2 & MS2_ADRSERR)
+ else if (csr2 & MS2_ADRSERR)
type = "address parity err";
- else if (mcr->ms_csr2 & MS2_RDSERR)
+ else if (csr2 & MS2_RDSERR)
type = "rds err";
- else if (mcr->ms_csr2 & MS2_CRDERR) {
+ else if (csr2 & MS2_CRDERR) {
hard = 0;
type = "";
} else
type = "mysterious error";
printf("%s: %s%s%s addr %x bank %x syn %x\n",
- mc->mem_dev.dv_xname,
- hard ? "hard error: " : "soft ecc",
- type, mcr->ms_csr2 & MS2_HIERR ?
- " (+ other rds or crd err)" : "",
- ((mcr->ms_csr2 & MS2_ADDR) + mcr->biic.bi_sadr) >> 9,
- (mcr->ms_csr2 & MS2_INTLVADDR) != 0,
- mcr->ms_csr2 & MS2_SYN);
- mcr->ms_csr1 = mcr->ms_csr1 | MS1_CRDINH;
- mcr->ms_csr2 = mcr->ms_csr2;
+ sc->sc_dev.dv_xname, hard ? "hard error: " : "soft ecc",
+ type, csr2 & MS2_HIERR ? " (+ other rds or crd err)" : "",
+ ((csr2 & MS2_ADDR) + MEMRD(BIREG_SADR)) >> 9,
+ (csr2 & MS2_INTLVADDR) != 0, csr2 & MS2_SYN);
+ MEMWR(MSREG_CSR1, csr1 | MS1_CRDINH);
+ MEMWR(MSREG_CSR2, csr2);
}
}
/*
* Receive a character from logical console.
*/
-rxcdintr()
+void
+rxcdintr(arg)
+ int arg;
{
register int c = mfpr(PR_RXCD);
-/* $OpenBSD: ka860.c,v 1.4 1997/09/10 12:04:49 maja Exp $ */
-/* $NetBSD: ka860.c,v 1.7 1997/02/19 10:04:20 ragge Exp $ */
+/* $OpenBSD: ka860.c,v 1.5 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: ka860.c,v 1.15 1999/08/07 10:36:49 ragge Exp $ */
/*
* Copyright (c) 1986, 1988 Regents of the University of California.
* All rights reserved.
/*
* VAX 8600 specific routines.
+ * Also contains abus spec's and memory init routines.
*/
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-
#include <machine/cpu.h>
#include <machine/clock.h>
#include <machine/mtpr.h>
#include <machine/ioa.h>
#include <machine/sid.h>
-struct ioa *ioa;
+#include <vax/vax/gencons.h>
-void ka86_conf __P((struct device *, struct device *, void *));
-void ka86_memenable __P((struct sbi_attach_args *, struct device *));
-void ka86_memerr __P((void));
-int ka86_mchk __P((caddr_t));
-void ka86_steal_pages __P((void));
+static void ka86_memerr __P((void));
+static int ka86_mchk __P((caddr_t));
+static void ka86_reboot __P((int));
+static void ka86_clrf __P((void));
+static void ka860_init __P((struct device *));
void crlattach __P((void));
struct cpu_dep ka860_calls = {
- ka86_steal_pages,
- generic_clock,
+ 0,
ka86_mchk,
ka86_memerr,
- ka86_conf,
+ 0,
generic_clkread,
generic_clkwrite,
6, /* ~VUPS */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
- 0, /* Used by vaxstation */
-
+ 10, /* SCB pages */
+ 0, /* Halt call, nothing special */
+ ka86_reboot,
+ ka86_clrf,
};
/*
#define M8600_MSTAT2_BITS "\20\20CP_BYT_WR\17ABUS_BD_DT_CODE\10MULT_ERR\
\7CHE_TAG_PE\6CHE_TAG_W_PE\5CHE_WRTN_BIT\4NXM\3CP-IO_BUF_ERR\2MBOX_LOCK"
-/* enable CRD reports */
-void
-ka86_memenable(sa, dev)
- struct sbi_attach_args *sa; /* XXX */
- struct device *dev;
-{
- mtpr(mfpr(PR_MERG) & ~M8600_ICRD, PR_MERG);
-}
-
/* log CRD errors */
void
ka86_memerr()
return (MCHK_PANIC);
}
-void
-ka86_steal_pages()
-{
- extern vm_offset_t avail_start, virtual_avail;
- extern struct nexus *nexus;
- int junk;
-
- /* 8600 may have 2 SBI's == 4 pages */
- MAPPHYS(junk, 4, VM_PROT_READ|VM_PROT_WRITE);
-
- /* Map in ioa register space */
- MAPVIRT(ioa, MAXNIOA);
- pmap_map((vm_offset_t)ioa, (u_int)IOA8600(0),
- (u_int)IOA8600(0) + IOAMAPSIZ, VM_PROT_READ|VM_PROT_WRITE);
- pmap_map((vm_offset_t)ioa + IOAMAPSIZ, (u_int)IOA8600(1),
- (u_int)IOA8600(1) + IOAMAPSIZ, VM_PROT_READ|VM_PROT_WRITE);
- pmap_map((vm_offset_t)ioa + 2 * IOAMAPSIZ, (u_int)IOA8600(2),
- (u_int)IOA8600(2) + IOAMAPSIZ, VM_PROT_READ|VM_PROT_WRITE);
- pmap_map((vm_offset_t)ioa + 3 * IOAMAPSIZ, (u_int)IOA8600(3),
- (u_int)IOA8600(3) + IOAMAPSIZ, VM_PROT_READ|VM_PROT_WRITE);
-
- /* Map in possible nexus space */
- MAPVIRT(nexus, btoc(NEXSIZE * MAXNNEXUS));
- pmap_map((vm_offset_t)nexus, (u_int)NEXA8600,
- (u_int)NEXA8600 + NNEX8600 * NEXSIZE, VM_PROT_READ|VM_PROT_WRITE);
- pmap_map((vm_offset_t)&nexus[NNEXSBI], (u_int)NEXB8600,
- (u_int)NEXB8600 + NNEX8600 * NEXSIZE, VM_PROT_READ|VM_PROT_WRITE);
-}
-
struct ka86 {
unsigned snr:12,
plant:4,
};
void
-ka86_conf(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ka860_init(self)
+ struct device *self;
{
- extern char cpu_model[];
struct ka86 *ka86 = (void *)&vax_cpudata;
/* Enable cache */
mtpr(3, PR_CSWP);
- strcpy(cpu_model,"VAX 8600");
- if (ka86->v8650)
- cpu_model[5] = '5';
- printf(": %s, serial number %d(%d), hardware ECO level %d(%d)\n",
- &cpu_model[4], ka86->snr, ka86->plant, ka86->eco >> 4, ka86->eco);
- printf("%s: ", self->dv_xname);
+ printf(": CPU serial number %d(%d), hardware ECO level %d(%d)\n%s: ",
+ ka86->snr, ka86->plant, ka86->eco >> 4, ka86->eco, self->dv_xname);
if (mfpr(PR_ACCS) & 255) {
printf("FPA present, type %d, serial number %d, enabling.\n",
mfpr(PR_ACCS) & 255, mfpr(PR_ACCS) >> 16);
mtpr(0x8000, PR_ACCS);
} else
printf("no FPA\n");
+ /* enable CRD reports */
+ mtpr(mfpr(PR_MERG) & ~M8600_ICRD, PR_MERG);
crlattach();
}
+
+/*
+ * Clear restart flag.
+ */
+void
+ka86_clrf()
+{
+ /*
+ * We block all interrupts here so that there won't be any
+ * interrupts for an ongoing printout.
+ */
+ int s = splhigh(), old = mfpr(PR_TXCS);
+
+#define WAIT while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
+
+ WAIT;
+
+ /* Enable channel to console */
+ mtpr(GC_LT|GC_WRT, PR_TXCS);
+ WAIT;
+
+ /* clear warm start flag */
+ mtpr(GC_CWFL, PR_TXDB);
+ WAIT;
+
+ /* clear cold start flag */
+ mtpr(GC_CCFL, PR_TXDB);
+ WAIT;
+
+ /* restore old state */
+ mtpr(old|GC_WRT, PR_TXCS);
+ splx(s);
+}
+
+void
+ka86_reboot(howto)
+ int howto;
+{
+ WAIT;
+
+ /* Enable channel to console */
+ mtpr(GC_LT|GC_WRT, PR_TXCS);
+ WAIT;
+
+ mtpr(GC_BTFL, PR_TXDB);
+ WAIT;
+
+ asm("halt");
+}
+
+static int abus_print __P((void *, const char *));
+static int abus_match __P((struct device *, struct cfdata *, void *));
+static void abus_attach __P((struct device *, struct device *, void*));
+
+struct cfattach abus_ca = {
+ sizeof(struct device), abus_match, abus_attach
+};
+
+/*
+ * Abus is the master bus on VAX 8600.
+ */
+int
+abus_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ if (vax_bustype == VAX_ABUS)
+ return 1;
+ return 0;
+}
+
+void
+abus_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ volatile int tmp;
+ volatile struct sbia_regs *sbiar;
+ struct ioa *ioa;
+ int type, i;
+ struct bp_conf bp;
+
+ /*
+ * Init CPU.
+ */
+ ka860_init(self);
+
+ for (i = 0; i < MAXNIOA; i++) {
+ ioa = (struct ioa *)vax_map_physmem((paddr_t)IOA8600(0),
+ (IOAMAPSIZ / VAX_NBPG));
+ if (badaddr((caddr_t)ioa, 4)) {
+ vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG));
+ continue;
+ }
+ tmp = ioa->ioacsr.ioa_csr;
+ type = tmp & IOA_TYPMSK;
+
+ switch (type) {
+
+ case IOA_SBIA:
+ bp.type = "sbi";
+ bp.num = i;
+ config_found(self, &bp, abus_print);
+ sbiar = (void *)ioa;
+ sbiar->sbi_errsum = -1;
+ sbiar->sbi_error = 0x1000;
+ sbiar->sbi_fltsts = 0xc0000;
+ break;
+
+ default:
+ printf("IOAdapter %x unsupported\n", type);
+ break;
+ }
+ vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG));
+ }
+}
+
+int
+abus_print(aux, hej)
+ void *aux;
+ const char *hej;
+{
+ struct bp_conf *bp = aux;
+ if (hej)
+ printf("%s at %s", bp->type, hej);
+ return (UNCONF);
+}
-/* $OpenBSD: locore.c,v 1.9 1997/09/10 12:04:50 maja Exp $ */
-/* $NetBSD: locore.c,v 1.21 1997/04/06 20:37:05 ragge Exp $ */
+/* $OpenBSD: locore.c,v 1.10 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: locore.c,v 1.43 2000/03/26 11:39:45 ragge Exp $ */
/*
- * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <sys/param.h>
-#include <sys/types.h>
#include <sys/reboot.h>
#include <sys/device.h>
#include <sys/systm.h>
+#include <sys/user.h>
#include <vm/vm.h>
-#include <dev/cons.h>
-
#include <machine/cpu.h>
#include <machine/sid.h>
#include <machine/param.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
+#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/nexus.h>
void start __P((void));
void main __P((void));
-u_int proc0paddr, esym;
-int *Sysmap, bootdev;
+extern paddr_t avail_end;
+paddr_t esym;
+u_int proc0paddr;
-/*
- * We set up some information about the machine we're
- * running on and thus initializes/uses vax_cputype and vax_boardtype.
- * There should be no need to change/reinitialize these variables
- * outside of this routine, they should be read only!
- */
-int vax_cputype; /* highest byte of SID register */
-int vax_bustype; /* holds/defines all busses on this machine */
-int vax_boardtype; /* machine dependend, combination of SID and SIE */
-int vax_systype; /* machine dependend identification of the system */
-
-int vax_cpudata; /* contents of the SID register */
-int vax_siedata; /* contents of the SIE register */
-int vax_confdata; /* machine dependend, configuration/setup data */
/*
- * Also; the strict cpu-dependent information is set up here, in
+ * The strict cpu-dependent information is set up here, in
* form of a pointer to a struct that is specific for each cpu.
*/
extern struct cpu_dep ka780_calls;
extern struct cpu_dep ka860_calls;
extern struct cpu_dep ka820_calls;
extern struct cpu_dep ka43_calls;
+extern struct cpu_dep ka46_calls;
+extern struct cpu_dep ka48_calls;
+extern struct cpu_dep ka49_calls;
extern struct cpu_dep ka410_calls;
extern struct cpu_dep ka630_calls;
extern struct cpu_dep ka650_calls;
+extern struct cpu_dep ka660_calls;
+extern struct cpu_dep ka670_calls;
/*
* Start is called from boot; the first routine that is called
void
start()
{
- register __boothowto asm ("r11");
- register __bootdev asm ("r10");
- register __esym asm ("r9");
- register __physmem asm ("r8");
- extern vm_offset_t avail_end;
- extern u_int *end;
- extern void *scratch;
- register tmpptr;
+ extern char cpu_model[];
+ extern void *scratch;
+ struct pte *pt;
- /*
- * We get parameters passed in registers from boot, put
- * them in memory to save.
- */
- boothowto = __boothowto;
- bootdev = __bootdev;
- esym = __esym | 0x80000000;
- avail_end = __physmem; /* Better to take from RPB, if available */
+ mtpr(AST_NO, PR_ASTLVL); /* Turn off ASTs */
- asm("pushl $0x001f0000;pushl $to;rei;to:movw $0xfff, _panic");
+ findcpu(); /* Set up the CPU identifying variables */
- /*
- * FIRST we must set up kernel stack, directly after end.
- * This is the only thing we have to setup here, rest in pmap.
- */
- PAGE_SIZE = NBPG * 2; /* Set logical page size */
-#ifdef DDB
- if ((boothowto & RB_KDB) != 0)
- proc0paddr = ROUND_PAGE(esym);
+ if (vax_confdata & 0x80)
+ strcpy(cpu_model, "MicroVAX ");
else
-#endif
- proc0paddr = ROUND_PAGE(&end);
-
- tmpptr = proc0paddr & 0x7fffffff;
- mtpr(tmpptr, PR_PCBB); /* must be set before ksp for some cpus */
- mtpr(proc0paddr + UPAGES * NBPG, PR_KSP); /* new kernel stack */
+ strcpy(cpu_model, "VAXstation ");
- /*
- * Set logical page size and put Sysmap on its place.
- */
- Sysmap = (u_int *)ROUND_PAGE(mfpr(PR_KSP));
-
- /* Be sure some important internal registers have safe values */
- ((struct pcb *)proc0paddr)->P0LR = 0;
- ((struct pcb *)proc0paddr)->P0BR = (void *)0x80000000;
- ((struct pcb *)proc0paddr)->P1LR = 0;
- ((struct pcb *)proc0paddr)->P1BR = (void *)0x80000000;
- ((struct pcb *)proc0paddr)->iftrap = NULL;
- mtpr(0, PR_P0LR);
- mtpr(0x80000000, PR_P0BR);
- mtpr(0, PR_P1LR);
- mtpr(0x80000000, PR_P1BR);
-
- mtpr(0, PR_SCBB); /* SCB at physical addr */
- mtpr(0, PR_ESP); /* Must be zero, used in page fault routine */
- mtpr(AST_NO, PR_ASTLVL);
-
- /* Count up memory etc... early machine dependent routines */
- vax_cputype = ((vax_cpudata = mfpr(PR_SID)) >> 24);
-
- switch (vax_cputype) {
+ switch (vax_boardtype) {
#if VAX780
- case VAX_TYP_780:
- vax_bustype = VAX_SBIBUS | VAX_CPUBUS;
- vax_boardtype = VAX_BTYP_780;
+ case VAX_BTYP_780:
dep_call = &ka780_calls;
+ strcpy(cpu_model,"VAX 11/780");
+ if (vax_cpudata & 0x100)
+ cpu_model[9] = '5';
break;
#endif
#if VAX750
- case VAX_TYP_750:
- vax_bustype = VAX_CMIBUS | VAX_CPUBUS;
- vax_boardtype = VAX_BTYP_750;
+ case VAX_BTYP_750:
dep_call = &ka750_calls;
+ strcpy(cpu_model, "VAX 11/750");
break;
#endif
#if VAX8600
- case VAX_TYP_790:
- vax_bustype = VAX_CPUBUS | VAX_MEMBUS;
- vax_boardtype = VAX_BTYP_790;
+ case VAX_BTYP_790:
dep_call = &ka860_calls;
+ strcpy(cpu_model,"VAX 8600");
+ if (vax_cpudata & 0x100)
+ cpu_model[6] = '5';
break;
#endif
-#if VAX630 || VAX650 || VAX410 || VAX43
- case VAX_TYP_UV2:
- case VAX_TYP_CVAX:
- case VAX_TYP_RIGEL:
- vax_siedata = *(int *)(0x20040004); /* SIE address */
- vax_boardtype = (vax_cputype<<24) | ((vax_siedata>>24)&0xFF);
-
- switch (vax_boardtype) {
#if VAX410
- case VAX_BTYP_420: /* They are very similar */
- case VAX_BTYP_410:
- dep_call = &ka410_calls;
- vax_confdata = *(int *)(0x20020000);
- vax_bustype = VAX_VSBUS | VAX_CPUBUS;
- break;
+ case VAX_BTYP_420: /* They are very similar */
+ dep_call = &ka410_calls;
+ if (((vax_siedata >> 8) & 0xff) == 1)
+ strcat(cpu_model, "/m{38,48}");
+ else if (((vax_siedata >> 8) & 0xff) == 0)
+ strcat(cpu_model, "/m{30,40}");
+ break;
+
+ case VAX_BTYP_410:
+ dep_call = &ka410_calls;
+ strcat(cpu_model, "2000");
+ break;
#endif
#if VAX43
- case VAX_BTYP_43:
- vax_confdata = *(int *)(0x20020000);
- vax_bustype = VAX_VSBUS | VAX_CPUBUS;
- dep_call = &ka43_calls;
- break;
+ case VAX_BTYP_43:
+ dep_call = &ka43_calls;
+ strcat(cpu_model, "3100/m76");
+ break;
+#endif
+#if VAX46
+ case VAX_BTYP_46:
+ dep_call = &ka46_calls;
+ strcat(cpu_model, "4000/60");
+ break;
+#endif
+#if VAX48
+ case VAX_BTYP_48:
+ dep_call = &ka48_calls;
+ strcat(cpu_model, "4000 VLC");
+ break;
+#endif
+#if VAX49
+ case VAX_BTYP_49:
+ dep_call = &ka49_calls;
+ strcat(cpu_model, "4000/90");
+ break;
#endif
#if VAX630
- case VAX_BTYP_630:
- dep_call = &ka630_calls;
- vax_bustype = VAX_UNIBUS | VAX_CPUBUS;
- break;
+ case VAX_BTYP_630:
+ dep_call = &ka630_calls;
+ strcpy(cpu_model,"MicroVAX II");
+ break;
#endif
#if VAX650
- case VAX_BTYP_650:
- vax_bustype = VAX_UNIBUS | VAX_CPUBUS;
- dep_call = &ka650_calls;
+ case VAX_BTYP_650:
+ dep_call = &ka650_calls;
+ strcpy(cpu_model,"MicroVAX ");
+ switch ((vax_siedata >> 8) & 255) {
+ case VAX_SIE_KA640:
+ strcat(cpu_model, "3300/3400");
break;
-#endif
+
+ case VAX_SIE_KA650:
+ strcat(cpu_model, "3500/3600");
+ break;
+
+ case VAX_SIE_KA655:
+ strcat(cpu_model, "3800/3900");
+ break;
+
default:
+ strcat(cpu_model, "III");
break;
}
break;
#endif
+#if VAX660
+ case VAX_BTYP_660:
+ dep_call = &ka660_calls;
+ strcpy(cpu_model,"VAX 4000/200");
+ break;
+#endif
+#if VAX670
+ case VAX_BTYP_670:
+ dep_call = &ka670_calls;
+ strcpy(cpu_model,"VAX 4000/300");
+ break;
+#endif
#if VAX8200
- case VAX_TYP_8SS:
- vax_boardtype = VAX_BTYP_8000;
- vax_bustype = VAX_BIBUS;
+ case VAX_BTYP_8000:
mastercpu = mfpr(PR_BINID);
dep_call = &ka820_calls;
+ strcpy(cpu_model, "VAX 8200");
break;
#endif
default:
asm("halt");
}
+ /*
+ * Machines older than MicroVAX II have their boot blocks
+ * loaded directly or the boot program loaded from console
+ * media, so we need to figure out their memory size.
+ * This is not easily done on MicroVAXen, so we get it from
+ * VMB instead.
+ */
+ if (avail_end == 0)
+ while (badaddr((caddr_t)avail_end, 4) == 0)
+ avail_end += VAX_NBPG * 128;
+
+ avail_end = TRUNC_PAGE(avail_end); /* be sure */
+
+ proc0.p_addr = (void *)proc0paddr; /* XXX */
+
+ /* Clear the used parts of the uarea except for the pcb */
+ bzero(&proc0.p_addr->u_stats, sizeof(struct user) - sizeof(struct pcb));
+
pmap_bootstrap();
+ /* Now running virtual. set red zone for proc0 */
+ pt = kvtopte((u_int)proc0.p_addr + REDZONEADDR);
+ pt->pg_v = 0;
+
((struct pcb *)proc0paddr)->framep = scratch;
/*
-/* $OpenBSD: machdep.c,v 1.21 2000/03/23 09:59:56 art Exp $ */
-/* $NetBSD: machdep.c,v 1.45 1997/07/26 10:12:49 ragge Exp $ */
+/* $OpenBSD: machdep.c,v 1.22 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: machdep.c,v 1.96 2000/03/19 14:56:53 ragge Exp $ */
/*
- * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
* Copyright (c) 1993 Adam Glass
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
* @(#)machdep.c 7.16 (Berkeley) 6/3/91
*/
+#include <sys/signal.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/map.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/time.h>
-#include <sys/signal.h>
#include <sys/kernel.h>
-#include <sys/reboot.h>
#include <sys/msgbuf.h>
#include <sys/buf.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/ptrace.h>
+#include <vm/vm.h>
+#include <sys/sysctl.h>
+
+#include <dev/cons.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
#ifdef SYSVMSG
#include <sys/msg.h>
#endif
#include <sys/shm.h>
#endif
-#include <vm/vm_kern.h>
-
#include <net/netisr.h>
#include <net/if.h>
#ifdef INET
#include <netinet/in.h>
-#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#endif
+#ifdef NETATALK
+#include <netatalk/at_extern.h>
+#endif
#ifdef NS
#include <netns/ns_var.h>
#endif
-#include "ppp.h" /* For NERISR_PPP */
-#include "bridge.h" /* For NERISR_BRIDGE */
+#include "ppp.h" /* For NPPP */
+#include "bridge.h" /* For NBRIDGE */
#if NPPP > 0
#include <net/ppp_defs.h>
#include <net/if_ppp.h>
#include <ddb/db_extern.h>
#endif
-void netintr __P((void));
-void machinecheck __P((caddr_t));
-void cmrerr __P((void));
-int bufcalc __P((void));
+#include "smg.h"
-extern vm_offset_t avail_end;
-extern vm_offset_t virtual_avail, virtual_end;
+caddr_t allocsys __P((caddr_t));
+extern int *chrtoblktbl;
+extern int virtual_avail, virtual_end;
/*
* We do these external declarations here, maybe they should be done
* somewhere else...
*/
-int nmcr, nmba, numuba, cold = 1;
-caddr_t mcraddr[MAXNMCR];
-int astpending;
int want_resched;
char machine[] = MACHINE; /* from <machine/param.h> */
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
char cpu_model[100];
-int msgbufmapped = 0;
-struct msgbuf *msgbufp;
int physmem;
-struct cfdriver nexuscd;
-int todrstopped = 0, glurg;
int dumpsize = 0;
+int cold = 1; /* coldstart */
-caddr_t allocsys __P((caddr_t));
+#define IOMAPSZ 100
+static struct map iomap[IOMAPSZ];
-#define valloclim(name, type, num, lim) \
- (name) = (type *)v; v = (caddr_t)((lim) = ((name) + (num)))
+vm_map_t exec_map = NULL;
+vm_map_t mb_map = NULL;
-#ifdef BUFPAGES
-int bufpages = BUFPAGES;
-#else
-int bufpages = 0;
-#endif
-int nswbuf = 0;
-#ifdef NBUF
-int nbuf = NBUF;
-#else
-int nbuf = 0;
+#ifdef DEBUG
+int iospace_inited = 0;
#endif
void
int base, residual, i, sz;
vm_offset_t minaddr, maxaddr;
vm_size_t size;
+ extern unsigned int avail_end;
/*
* Initialize error message buffer.
*/
- msgbufmapped = 1;
+ initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
-#if VAX750 || VAX650
- if (vax_cputype == VAX_750 || vax_cputype == VAX_650)
- if (!mfpr(PR_TODR))
- mtpr(todrstopped = 1, PR_TODR);
-#endif
/*
* Good {morning,afternoon,evening,night}.
+ * Also call CPU init on systems that need that.
*/
- printf("%s\n", version);
- printf("realmem = %d\n", avail_end);
+ printf("%s\n%s\n", version, cpu_model);
+ if (dep_call->cpu_conf)
+ (*dep_call->cpu_conf)();
+
+ printf("total memory = %d\n", avail_end);
physmem = btoc(avail_end);
panicstr = NULL;
mtpr(AST_NO, PR_ASTLVL);
* Find out how much space we need, allocate it, and then give
* everything true virtual addresses.
*/
- sz = (int)allocsys((caddr_t)0);
- if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0)
+
+ sz = (int) allocsys((caddr_t)0);
+ if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
panic("startup: no room for tables");
- if (allocsys(v) - v != sz)
+ if (((unsigned long)allocsys(v) - (unsigned long)v) != sz)
panic("startup: table size inconsistency");
-
/*
* Now allocate buffers proper. They are different than the above in
* that they usually occupy more virtual memory than physical.
*/
- size = MAXBSIZE * nbuf;
- buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
- &maxaddr, size, TRUE);
+ size = MAXBSIZE * nbuf; /* # bytes for buffers */
+
+ /* allocate VM for buffers... area is not managed by VM system */
+ if (uvm_map(kernel_map, (vm_offset_t *) &buffers, round_page(size),
+ NULL, UVM_UNKNOWN_OFFSET,
+ UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
+ UVM_ADV_NORMAL, 0)) != KERN_SUCCESS)
+ panic("cpu_startup: cannot allocate VM for buffers");
+
minaddr = (vm_offset_t) buffers;
- if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
- &minaddr, size, FALSE) != KERN_SUCCESS)
- panic("startup: cannot allocate buffers");
if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
/* don't want to alloc more physical mem than needed */
bufpages = btoc(MAXBSIZE) * nbuf;
}
base = bufpages / nbuf;
residual = bufpages % nbuf;
- for (i = 0; i < nbuf; i++) {
- vm_size_t curbufsize;
- vm_offset_t curbuf;
+ /* now allocate RAM for buffers */
+ for (i = 0 ; i < nbuf ; i++) {
+ vm_offset_t curbuf;
+ vm_size_t curbufsize;
+ struct vm_page *pg;
/*
* First <residual> buffers get (base+1) physical pages
* The rest of each buffer occupies virtual space, but has no
* physical memory allocated for it.
*/
- curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
+ curbuf = (vm_offset_t) buffers + i * MAXBSIZE;
curbufsize = CLBYTES * (i < residual ? base + 1 : base);
- vm_map_pageable(buffer_map, curbuf, curbuf + curbufsize,
- FALSE);
- vm_map_simplify(buffer_map, curbuf);
+ while (curbufsize) {
+ pg = uvm_pagealloc(NULL, 0, NULL, 0);
+ if (pg == NULL)
+ panic("cpu_startup: "
+ "not enough RAM for buffer cache");
+ pmap_enter(kernel_map->pmap, curbuf,
+ VM_PAGE_TO_PHYS(pg), VM_PROT_READ|VM_PROT_WRITE, TRUE,
+ VM_PROT_READ|VM_PROT_WRITE);
+ curbuf += PAGE_SIZE;
+ curbufsize -= PAGE_SIZE;
+ }
}
/*
* Allocate a submap for exec arguments. This map effectively limits
* the number of processes exec'ing at any time.
*/
- exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS,
- TRUE);
-
- /*
- * Finally, allocate mbuf pool. Since mclrefcnt is an off-size we
- * use the more space efficient malloc in place of kmem_alloc.
- */
- mclrefcnt = (char *)malloc(NMBCLUSTERS + CLBYTES / MCLBYTES, M_MBUF,
- M_NOWAIT);
- bzero(mclrefcnt, NMBCLUSTERS + CLBYTES / MCLBYTES);
- mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
- VM_MBUF_SIZE, FALSE);
-
- /*
- * Allocate a submap for physio
- */
- phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
- VM_PHYS_SIZE, TRUE);
-
+ exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
+
+ mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
+ M_MBUF, M_NOWAIT);
+ bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
+ mb_map = uvm_km_suballoc(kernel_map, (vaddr_t *)&mbutl, &maxaddr,
+ VM_MBUF_SIZE, VM_MAP_INTRSAFE, FALSE, NULL);
+
timeout_init();
- printf("avail mem = %d\n", (int)ptoa(cnt.v_free_count));
- printf("Using %d buffers containing %d bytes of memory.\n", nbuf,
- bufpages * CLBYTES);
+ printf("avail memory = %ld\n", ptoa(uvmexp.free));
+ printf("using %d buffers containing %d of memory\n", nbuf, bufpages * CLBYTES);
/*
* Set up buffers, so they can be used to read disk labels.
*/
- bufinit();
- /*
- * Configure the system.
- */
- if (boothowto & RB_CONFIG) {
-#ifdef BOOT_CONFIG
- user_config();
-#else
- printf("kernel does not support -c; continuing..\n");
-#endif
- }
+ bufinit();
configure();
}
-#ifndef BUFCACHEPERCENT
-#define BUFCACHEPERCENT 5
-#endif
-
-int
-bufcalc()
-{
- /*
- * Determine how many buffers to allocate. By default we allocate
- * the BSD standard of use 10% of memory for the first 2 Meg,
- * 5% of remaining. But this might cause systems with large
- * core (32MB) to fail to boot due to small KVM space. Reduce
- * BUFCACHEPERCENT in this case. Insure a minimum of 16 buffers.
- */
- if (bufpages == 0) {
- /* We always have more than 2MB of memory. */
- bufpages = btoc(avail_end + 2 * 1024 * 1024) /
- ((100 / BUFCACHEPERCENT) * CLSIZE);
- }
- if (nbuf == 0)
- nbuf = bufpages;
-
- /* Restrict to at most 70% filled kvm */
- if (nbuf * MAXBSIZE >
- (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) * 7 / 10)
- nbuf = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) /
- MAXBSIZE * 7 / 10;
-
- /* We really need some buffers. */
- if (nbuf < 16)
- nbuf = 16;
-
- /* More buffer pages than fits into the buffer is senseless. */
- if (bufpages > nbuf * MAXBSIZE / CLBYTES) {
- bufpages = nbuf * MAXBSIZE / CLBYTES;
- return (bufpages * CLSIZE);
- }
- return (nbuf * MAXBSIZE / NBPG);
-}
-
-/*
- * Allocate space for system data structures. We are given a starting
- * virtual address and we return a final virtual address; along the way we
- * set each data structure pointer.
- *
- * We call allocsys() with 0 to find out how much space we want, allocate that
- * much and fill it with zeroes, and then call allocsys() again with the
- * correct base virtual address.
- */
-caddr_t
-allocsys(v)
- register caddr_t v;
-{
-#define valloc(name, type, num) v = (caddr_t)(((name) = (type *)v) + (num))
-
-#ifdef REAL_CLISTS
- valloc(cfree, struct cblock, nclist);
-#endif
- valloc(timeouts, struct timeout, ntimeout);
-#ifdef SYSVSHM
- valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
-#endif
-#ifdef SYSVSEM
- valloc(sema, struct semid_ds, seminfo.semmni);
- valloc(sem, struct sem, seminfo.semmns);
-
- /* This is pretty disgusting! */
- valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
-#endif
-#ifdef SYSVMSG
- valloc(msgpool, char, msginfo.msgmax);
- valloc(msgmaps, struct msgmap, msginfo.msgseg);
- valloc(msghdrs, struct msg, msginfo.msgtql);
- valloc(msqids, struct msqid_ds, msginfo.msgmni);
-#endif
-
- /* Allocate 1/2 as many swap buffer headers as file i/o buffers. */
- if (nswbuf == 0) {
- nswbuf = (nbuf / 2) & ~1; /* force even */
- if (nswbuf > 256)
- nswbuf = 256; /* sanity */
- }
- valloc(swbuf, struct buf, nswbuf);
- valloc(buf, struct buf, nbuf);
- return (v);
-}
-
long dumplo = 0;
long dumpmag = 0x8fca0101;
void
-dumpconf()
+cpu_dumpconf()
{
int nblks;
- extern int dumpdev;
/*
* XXX include the final RAM page which is not included in physmem.
dumplo = btodb(CLBYTES);
}
-void
-cpu_initclocks()
-{
- (*dep_call->cpu_clock)();
-}
-
int
cpu_sysctl(a, b, c, d, e, f, g)
int *a;
void
consinit()
{
+ /*
+ * Init I/O memory resource map. Must be done before cninit()
+ * is called; we may want to use iospace in the console routines.
+ */
+ rminit(iomap, IOSPSZ, (long)1, "iomap", IOMAPSZ);
+#ifdef DEBUG
+ iospace_inited = 1;
+#endif
cninit();
#ifdef DDB
-/* db_machine_init(); */
- ddb_init();
+ {
+ extern int end; /* Contains pointer to symsize also */
+ extern int *esym;
+
+ ddb_init();
+ }
+#ifdef DEBUG
+ if (sizeof(struct user) > REDZONEADDR)
+ panic("struct user inside red zone");
+#endif
#ifdef donotworkbyunknownreason
if (boothowto & RB_KDB)
Debugger();
void *v;
register_t *retval;
{
- struct sys_sigreturn_args /* {
+ struct sys_sigreturn_args {
syscallarg(struct sigcontext *) sigcntxp;
- } */ *uap = v;
+ } *uap = v;
struct trapframe *scf;
struct sigcontext *cntx;
scf = p->p_addr->u_pcb.framep;
cntx = SCARG(uap, sigcntxp);
+ if (uvm_useracc((caddr_t)cntx, sizeof (*cntx), B_READ) == 0)
+ return EINVAL;
/* Compatibility mode? */
if ((cntx->sc_ps & (PSL_IPL | PSL_IS)) ||
((cntx->sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
- p->p_sigmask = cntx->sc_mask & ~sigcantmask;
+ /* Restore signal mask. */
+ p->p_sigmask = cntx->sc_mask & ~sigcantmask;
scf->fp = cntx->sc_fp;
scf->ap = cntx->sc_ap;
sig_t catcher;
int sig, mask;
u_long code;
- int type;
- union sigval val;
+ int type;
+ union sigval val;
{
- struct proc *p = curproc;
- struct sigacts *psp = p->p_sigacts;
- struct trapframe *syscf;
- struct sigcontext *sigctx;
- struct trampframe *trampf;
- unsigned cursp;
- int oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
- extern char sigcode[], esigcode[];
- int fsize, rndfsize, kscsize;
- siginfo_t *sip, ksi;
+ struct proc *p = curproc;
+ struct sigacts *psp = p->p_sigacts;
+ struct trapframe *syscf;
+ struct sigcontext *sigctx, gsigctx;
+ struct trampframe *trampf, gtrampf;
+ extern char sigcode[], esigcode[];
+ unsigned cursp;
+ int onstack;
- /*
- * Allocate and validate space for the signal handler context. Note
- * that if the stack is in P0 space, the call to grow() is a nop, and
- * the useracc() check will fail if the process has not already
- * allocated the space with a `brk'. We shall allocate space on the
- * stack for both struct sigcontext and struct calls...
- */
syscf = p->p_addr->u_pcb.framep;
- fsize = sizeof *sigctx;
- rndfsize = ((fsize + 7) / 8) * 8; /* XXX */
- kscsize = rndfsize;
- if (psp->ps_siginfo & sigmask(sig)) {
- fsize += sizeof ksi;
- rndfsize = ((fsize + 7) / 8) * 8; /* XXX */
- }
- /* First check what stack to work on */
- if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
- (psp->ps_sigonstack & sigmask(sig))) {
- cursp = (int)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size -
- rndfsize);
- psp->ps_sigstk.ss_flags |= SS_ONSTACK;
- } else
- cursp = syscf->sp - rndfsize;
- if (cursp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
- (void)grow(p, cursp);
+ onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+
+ /* Allocate space for the signal handler context. */
+ if (onstack)
+ cursp = ((int)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size);
+ else
+ cursp = syscf->sp;
/* Set up positions for structs on stack */
- sigctx = (struct sigcontext *)(cursp - sizeof(struct sigcontext));
- trampf = (struct trampframe *)((unsigned)sigctx -
+ sigctx = (struct sigcontext *) (cursp - sizeof(struct sigcontext));
+ trampf = (struct trampframe *) ((unsigned)sigctx -
sizeof(struct trampframe));
/* Place for pointer to arg list in sigreturn */
cursp = (unsigned)sigctx - 8;
- if (useracc((caddr_t)cursp, fsize, B_WRITE) == 0) {
- /*
- * Process has trashed its stack; give it an illegal
- * instruction to halt it in its tracks.
- */
- SIGACTION(p, SIGILL) = SIG_DFL;
- sig = sigmask(SIGILL);
- p->p_sigignore &= ~sig;
- p->p_sigcatch &= ~sig;
- p->p_sigmask &= ~sig;
- psignal(p, SIGILL);
- return;
- }
+ gtrampf.arg = (int) sigctx;
+ gtrampf.pc = (unsigned) catcher;
+ gtrampf.scp = (int) sigctx;
+ gtrampf.code = code;
+ gtrampf.sig = sig;
+
+ gsigctx.sc_pc = syscf->pc;
+ gsigctx.sc_ps = syscf->psl;
+ gsigctx.sc_ap = syscf->ap;
+ gsigctx.sc_fp = syscf->fp;
+ gsigctx.sc_sp = syscf->sp;
+ gsigctx.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+ gsigctx.sc_mask = mask;
+
+#if defined(COMPAT_13) || defined(COMPAT_ULTRIX)
+ native_sigset_to_sigset13(mask, &gsigctx.__sc_mask13);
+#endif
- /* Set up pointers for sigreturn args */
- trampf->arg = (int) sigctx;
- trampf->pc = (unsigned) catcher;
- trampf->scp = (int) sigctx;
- trampf->code = code;
- trampf->sig = sig;
-
- sigctx->sc_pc = syscf->pc;
- sigctx->sc_ps = syscf->psl;
- sigctx->sc_ap = syscf->ap;
- sigctx->sc_fp = syscf->fp;
- sigctx->sc_sp = syscf->sp;
- sigctx->sc_onstack = oonstack;
- sigctx->sc_mask = mask;
+ if (copyout(>rampf, trampf, sizeof(gtrampf)) ||
+ copyout(&gsigctx, sigctx, sizeof(gsigctx)))
+ sigexit(p, SIGILL);
syscf->pc = (unsigned) (((char *) PS_STRINGS) - (esigcode - sigcode));
syscf->psl = PSL_U | PSL_PREVU;
syscf->ap = cursp;
syscf->sp = cursp;
- if (psp->ps_siginfo & sigmask(sig)) {
- initsiginfo(&ksi, sig, code, type, val);
- sip = (void *)cursp + kscsize;
- copyout((caddr_t)&ksi, (caddr_t)sip, fsize - kscsize);
- }
+ if (onstack)
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
}
int waittime = -1;
static volatile int showto; /* Must be volatile to survive MM on -> MM off */
void
-boot(howto /* , bootstr */)
- register howto;
-/* char *bootstr; */
+boot(howto)
+ register int howto;
{
- showto = howto;
if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
waittime = 0;
vfs_shutdown();
* If we've been adjusting the clock, the todr will be out of
* synch; adjust it now.
*/
- /*
- * If we've been adjusting the clock, the todr
- * will be out of synch; adjust it now unless
- * the system was sitting in ddb.
- */
- if ((howto & RB_TIMEBAD) == 0) {
- resettodr();
- } else {
- printf("WARNING: not updating battery clock\n");
- }
+ resettodr();
}
splhigh(); /* extreme priority */
if (howto & RB_HALT) {
if (dep_call->cpu_halt)
- (*dep_call->cpu_halt)();
+ (*dep_call->cpu_halt) ();
printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
for (;;)
;
*/
if (b)
while (*b) {
- showto |= (*b == 'a' ? RB_ASKBOOT :
- (*b == 'd' ? RB_DEBUG :
- (*b == 's' ? RB_SINGLE : 0)));
+ showto |= (*b == 'a' ? RB_ASKBOOT : (*b == 'd' ?
+ RB_DEBUG : (*b == 's' ? RB_SINGLE : 0)));
b++;
}
#endif
* rely on that.
*/
#ifdef notyet
- __asm volatile("movl sp, (0x80000200);"
- "movl 0x80000200, sp;"
- "mfpr $0x10, -(sp) # PR_PCBB;"
- "mfpr $0x11, -(sp) # PR_SCBB;"
- "mfpr $0xc, -(sp) # PR_SBR;"
- "mfpr $0xd, -(sp) # PR_SLR;"
- "mtpr $0, $0x38 # PR_MAPEN;");
+ asm(" movl sp, (0x80000200)
+ movl 0x80000200, sp
+ mfpr $0x10, -(sp) # PR_PCBB
+ mfpr $0x11, -(sp) # PR_SCBB
+ mfpr $0xc, -(sp) # PR_SBR
+ mfpr $0xd, -(sp) # PR_SLR
+ mtpr $0, $0x38 # PR_MAPEN
+ ");
#endif
if (showto & RB_DUMP)
if (dep_call->cpu_reboot)
(*dep_call->cpu_reboot)(showto);
- switch (vax_cputype) {
- int state;
-
-#if VAX750 || VAX780
- case VAX_780:
- case VAX_750:
- mtpr(GC_BOOT, PR_TXDB); /* boot command */
- break;
-#endif
-#if VAX8600
- case VAX_8600:
- state = mfpr(PR_TXCS);
- gencnputc(0, GC_LT | GC_WRT);
- mtpr(0x2, PR_TXDB); /* XXX */
- gencnputc(0, state | GC_WRT);
- break;
-#endif
- }
+ /* cpus that don't handle reboots get the standard reboot. */
+ while ((mfpr(PR_TXCS) & GC_RDY) == 0)
+ ;
+ mtpr(GC_CONS|GC_BTFL, PR_TXDB);
}
-
- /* How to boot */
- __asm volatile ("movl %0, r5" : : "g" (showto));
- __asm volatile ("movl %0, r11" : : "r" (showto)); /* ??? */
- __asm volatile ("halt");
- panic("Halt failed");
-}
-
-void
-netintr()
-{
-#ifdef INET
- if (netisr & (1 << NETISR_ARP)) {
- netisr &= ~(1 << NETISR_ARP);
- arpintr();
- }
- if (netisr & (1 << NETISR_IP)) {
- netisr &= ~(1 << NETISR_IP);
- ipintr();
- }
-#endif
-#ifdef INET6
- if (netisr & (1 << NETISR_IPV6)) {
- netisr &= ~(1 << NETISR_IPV6);
- ip6intr();
- }
-#endif
-#ifdef NETATALK
- if (netisr & (1 << NETISR_ATALK)) {
- netisr &= ~(1 << NETISR_ATALK);
- atintr();
- }
-#endif
-#ifdef NS
- if (netisr & (1 << NETISR_NS)) {
- netisr &= ~(1 << NETISR_NS);
- nsintr();
- }
-#endif
-#ifdef ISO
- if (netisr & (1 << NETISR_ISO)) {
- netisr &= ~(1 << NETISR_ISO);
- clnlintr();
- }
-#endif
-#ifdef CCITT
- if (netisr & (1 << NETISR_CCITT)) {
- netisr &= ~(1 << NETISR_CCITT);
- ccittintr();
- }
-#endif
-#if NPPP > 0
- if (netisr & (1 << NETISR_PPP)) {
- pppintr();
- }
-#endif
-#if NBRIDGE > 0
- if (netisr & (1 << NETISR_BRIDGE)) {
- bridgeintr();
- }
-#endif
-}
-
-void
-machinecheck(frame)
- caddr_t frame;
-{
- if ((*dep_call->cpu_mchk)(frame) == 0)
- return;
- (*dep_call->cpu_memerr)();
- panic("machine check");
+ asm("movl %0, r5":: "g" (showto)); /* How to boot */
+ asm("movl %0, r11":: "r"(showto)); /* ??? */
+ asm("halt");
+ panic("Halt sket sej");
}
void
dumpsys()
{
- extern int dumpdev;
+ extern int msgbufmapped;
msgbufmapped = 0;
if (dumpdev == NODEV)
* configured...
*/
if (dumpsize == 0)
- dumpconf();
- if (dumplo < 0)
+ cpu_dumpconf();
+ if (dumplo <= 0) {
+ printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
+ minor(dumpdev));
return;
- printf("\ndumping to dev %x, offset %d\n", dumpdev, (int)dumplo);
+ }
+ printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
+ minor(dumpdev), dumplo);
printf("dump ");
- switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev, 0, 0, 0)) {
+ switch ((*bdevsw[major(dumpdev)].d_dump) (dumpdev, 0, 0, 0)) {
case ENXIO:
printf("device bad\n");
}
}
-int
-fuswintr(addr)
- caddr_t addr;
-{
- panic("fuswintr: need to be implemented");
- return (0);
-}
-
-int
-suibyte(base, byte)
- void *base;
- short byte;
-{
- panic("suibyte: need to be implemented");
- return (0);
-}
-
-int
-suswintr(addr, cnt)
- caddr_t addr;
- u_int cnt;
-{
- panic("suswintr: need to be implemented");
- return (0);
-}
-
int
process_read_regs(p, regs)
struct proc *p;
regs->sp = tf->sp;
regs->pc = tf->pc;
regs->psl = tf->psl;
- return (0);
+ return 0;
}
int
tf->sp = regs->sp;
tf->pc = regs->pc;
tf->psl = regs->psl;
- return (0);
+ return 0;
}
int
if ((p->p_flag & P_INMEM) == 0)
return (EIO);
- ptr = (char *)p->p_addr->u_pcb.framep;
+ ptr = (char *) p->p_addr->u_pcb.framep;
tf = ptr;
- tf->pc = (unsigned)addr;
+ tf->pc = (unsigned) addr;
return (0);
}
return (0);
}
+#undef PHYSMEMDEBUG
+/*
+ * Allocates a virtual range suitable for mapping in physical memory.
+ * This differs from the bus_space routines in that it allocates on
+ * physical page sizes instead of logical sizes. This implementation
+ * uses resource maps when allocating space, which is allocated from
+ * the IOMAP submap. The implementation is similar to the uba resource
+ * map handling. Size is given in pages.
+ * If the page requested is bigger than a logical page, space is
+ * allocated from the kernel map instead.
+ *
+ * It is known that the first page in the iospace area is unused; it may
+ * be use by console device drivers (before the map system is inited).
+ */
+vaddr_t
+vax_map_physmem(phys, size)
+ paddr_t phys;
+ int size;
+{
+ extern vaddr_t iospace;
+ vaddr_t addr;
+ int pageno;
+ static int warned = 0;
+
+#ifdef DEBUG
+ if (!iospace_inited)
+ panic("vax_map_physmem: called before rminit()?!?");
+#endif
+ if (size >= LTOHPN) {
+ addr = uvm_km_valloc(kernel_map, size * VAX_NBPG);
+ if (addr == 0)
+ panic("vax_map_physmem: kernel map full");
+ } else {
+ pageno = rmalloc(iomap, size);
+ if (pageno == 0) {
+ if (warned++ == 0) /* Warn only once */
+ printf("vax_map_physmem: iomap too small");
+ return 0;
+ }
+ addr = iospace + (pageno * VAX_NBPG);
+ }
+ ioaccess(addr, phys, size);
+#ifdef PHYSMEMDEBUG
+ printf("vax_map_physmem: alloc'ed %d pages for paddr %lx, at %lx\n",
+ size, phys, addr);
+#endif
+ return addr | (phys & VAX_PGOFSET);
+}
+
+/*
+ * Unmaps the previous mapped (addr, size) pair.
+ */
void
-cmrerr()
+vax_unmap_physmem(addr, size)
+ vaddr_t addr;
+ int size;
{
- (*dep_call->cpu_memerr)();
+ extern vaddr_t iospace;
+ int pageno = (addr - iospace) / VAX_NBPG;
+#ifdef PHYSMEMDEBUG
+ printf("vax_unmap_physmem: unmapping %d pages at addr %lx\n",
+ size, addr);
+#endif
+ iounaccess(addr, size);
+ if (size >= LTOHPN)
+ uvm_km_free(kernel_map, addr, size * VAX_NBPG);
+ else
+ rmfree(iomap, size, pageno);
}
+
+/*
+ * Allocate space for system data structures. We are given a starting
+ * virtual address and we return a final virtual address; along the way we
+ * set each data structure pointer.
+ *
+ * We call allocsys() with 0 to find out how much space we want, allocate that
+ * much and fill it with zeroes, and then call allocsys() again with the
+ * correct base virtual address.
+ */
+caddr_t
+allocsys(v)
+ register caddr_t v;
+{
+#define valloc(name, type, num) v = (caddr_t)(((name) = (type *)v) + (num))
+
+#ifdef REAL_CLISTS
+ valloc(cfree, struct cblock, nclist);
+#endif
+ valloc(timeouts, struct timeout, ntimeout);
+#ifdef SYSVSHM
+ valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
+#endif
+#ifdef SYSVSEM
+ valloc(sema, struct semid_ds, seminfo.semmni);
+ valloc(sem, struct sem, seminfo.semmns);
+
+ /* This is pretty disgusting! */
+ valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
+#endif
+#ifdef SYSVMSG
+ valloc(msgpool, char, msginfo.msgmax);
+ valloc(msgmaps, struct msgmap, msginfo.msgseg);
+ valloc(msghdrs, struct msg, msginfo.msgtql);
+ valloc(msqids, struct msqid_ds, msginfo.msgmni);
+#endif
+
+#ifndef BUFCACHEPERCENT
+#define BUFCACHEPERCENT 5
+#endif
+ /*
+ * Determine how many buffers to allocate (enough to
+ * hold 5% of total physical memory, but at least 16).
+ * Allocate 1/2 as many swap buffer headers as file i/o buffers.
+ */
+ if (bufpages == 0)
+ bufpages = (physmem / ((100/BUFCACHEPERCENT) / CLSIZE));
+ if (nbuf == 0) {
+ nbuf = bufpages;
+ if (nbuf < 16)
+ nbuf = 16;
+ }
+ if (nbuf > 200)
+ nbuf = 200; /* or we run out of PMEGS */
+ /* Restrict to at most 70% filled kvm */
+ if (nbuf * MAXBSIZE >
+ (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) * 7 / 10)
+ nbuf = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
+ MAXBSIZE * 7 / 10;
+
+ /* More buffer pages than fits into the buffers is senseless. */
+ if (bufpages > nbuf * MAXBSIZE / CLBYTES)
+ bufpages = nbuf * MAXBSIZE / CLBYTES;
+
+ /* Allocate 1/2 as many swap buffer headers as file i/o buffers. */
+ if (nswbuf == 0) {
+ nswbuf = (nbuf / 2) & ~1; /* force even */
+ if (nswbuf > 256)
+ nswbuf = 256; /* sanity */
+ }
+ valloc(buf, struct buf, nbuf);
+ return (v);
+}
+
-/* $OpenBSD: mem.c,v 1.6 1999/11/22 19:22:03 matthieu Exp $ */
-/* $NetBSD: mem.c,v 1.9 1996/04/08 18:32:48 ragge Exp $ */
+/* $OpenBSD: mem.c,v 1.7 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: mem.c,v 1.15 1999/03/24 05:51:17 mrg Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
*/
/*
#include <vm/vm.h>
-extern unsigned int vmmap, avail_end;
+extern unsigned int avail_end;
caddr_t zeropage;
int mmopen __P((dev_t, int, int));
struct uio *uio;
int flags;
{
- register vm_offset_t o, v;
+ register vm_offset_t v;
register int c;
register struct iovec *iov;
int error = 0;
- static int physlock;
-
- if (minor(dev) == 0) {
- /* lock against other uses of shared vmmap */
- while (physlock > 0) {
- physlock++;
- error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
- "mmrw", 0);
- if (error)
- return (error);
- }
- physlock = 1;
- }
+
while (uio->uio_resid > 0 && error == 0) {
iov = uio->uio_iov;
if (iov->iov_len == 0) {
case 0:
v = uio->uio_offset;
if (v < 0 || v >= avail_end) {
- error = EFAULT;
- goto unlock;
+ return (EFAULT);
}
- pmap_enter(pmap_kernel(), (vm_offset_t)vmmap,
- trunc_page(v), uio->uio_rw == UIO_READ ?
- VM_PROT_READ : VM_PROT_WRITE, TRUE);
- o = uio->uio_offset & PAGE_MASK;
- c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
- error = uiomove((caddr_t)vmmap + o, c, uio);
- pmap_remove(pmap_kernel(), (vm_offset_t)vmmap,
- (vm_offset_t)vmmap + PAGE_SIZE);
+ c = min(iov->iov_len, MAXPHYS);
+ error = uiomove((caddr_t)v + KERNBASE, c, uio);
continue;
/* minor device 1 is kernel memory */
case 1:
v = uio->uio_offset;
c = min(iov->iov_len, MAXPHYS);
- if (!kernacc((caddr_t)v, c,
+ if (!uvm_kernacc((caddr_t)v, c,
uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
return (EFAULT);
error = uiomove((caddr_t)v, c, uio);
}
if (error)
break;
- iov->iov_base += c;
+ iov->iov_base = (caddr_t)iov->iov_base + c;
iov->iov_len -= c;
uio->uio_offset += c;
uio->uio_resid -= c;
}
- if (minor(dev) == 0) {
-unlock:
- if (physlock > 1)
- wakeup((caddr_t)&physlock);
- physlock = 0;
- }
return (error);
}
int off, prot;
{
- return (EOPNOTSUPP);
+ return (-1);
}
-/*ARGSUSED*/
int
mmioctl(dev, cmd, data, flags, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flags;
- struct proc *p;
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flags;
+ struct proc *p;
{
- return (EOPNOTSUPP);
+ return (EOPNOTSUPP);
}
-/* $OpenBSD: pmap.c,v 1.10 1997/10/02 19:51:50 niklas Exp $ */
-/* $NetBSD: pmap.c,v 1.37 1997/07/25 21:54:48 ragge Exp $ */
+/* $OpenBSD: pmap.c,v 1.11 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: pmap.c,v 1.74 1999/11/13 21:32:25 matt Exp $ */
/*
- * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1994, 1998, 1999 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/malloc.h>
+#include <sys/extent.h>
#include <sys/proc.h>
#include <sys/user.h>
-#include <sys/msgbuf.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/msgbuf.h>
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-#include <vm/vm_kern.h>
+#ifdef PMAPDEBUG
+#include <dev/cons.h>
+#endif
+
+#include <uvm/uvm.h>
#include <machine/pte.h>
#include <machine/pcb.h>
#include <machine/cpu.h>
#include <machine/scb.h>
-extern int bufcalc __P((void));
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_kern.h>
+
-static pt_entry_t *pmap_virt2pte __P((pmap_t, u_int));
-static pv_entry_t alloc_pv_entry __P((void));
-static void free_pv_entry __P((pv_entry_t));
-static int remove_pmap_from_mapping __P((pv_entry_t, pmap_t));
+/* QDSS console mapping hack */
+#include "qd.h"
+void qdearly(void);
-#define ISTACK_SIZE (4 * NBPG)
-#define PTE_TO_PV(pte) (PHYS_TO_PV((pte&PG_FRAME)<<PGSHIFT))
+#define ISTACK_SIZE NBPG
+vaddr_t istack;
+/*
+ * This code uses bitfield operators for most page table entries.
+ */
+#define PROTSHIFT 27
+#define PROT_KW (PG_KW >> PROTSHIFT)
+#define PROT_KR (PG_KR >> PROTSHIFT)
+#define PROT_RW (PG_RW >> PROTSHIFT)
+#define PROT_RO (PG_RO >> PROTSHIFT)
+#define PROT_URKW (PG_URKW >> PROTSHIFT)
struct pmap kernel_pmap_store;
-static int prot_array[]={ PG_NONE, PG_RO, PG_RW, PG_RW,
- PG_RO, PG_RO, PG_RW, PG_RW };
-
-static int kernel_prot[]={ PG_NONE, PG_KR, PG_KW, PG_KW,
- PG_RO,PG_KR,PG_KW,PG_URKW};
-
-static pv_entry_t pv_head = NULL;
-static unsigned int pv_count = 0;
-pv_entry_t pv_table; /* array of entries,
- one per LOGICAL page */
-unsigned *pte_cmap;
+struct pte *Sysmap; /* System page table */
+struct pv_entry *pv_table; /* array of entries, one per LOGICAL page */
+int pventries;
void *scratch;
+vaddr_t iospace;
+
+vaddr_t ptemapstart, ptemapend;
+struct extent *ptemap;
+#define PTMAPSZ EXTENT_FIXED_STORAGE_SIZE(100)
+char ptmapstorage[PTMAPSZ];
+
+#ifdef PMAPDEBUG
+volatile int recurse;
+#define RECURSESTART { \
+ if (recurse) \
+ printf("enter at %d, previous %d\n", __LINE__, recurse);\
+ recurse = __LINE__; \
+}
+#define RECURSEEND {recurse = 0; }
+#else
+#define RECURSESTART
+#define RECURSEEND
+#endif
#ifdef PMAPDEBUG
int startpmapdebug = 0;
-/* extern int startsysc, faultdebug; */
#endif
-unsigned int vmmap;
-vm_map_t pte_map;
+#ifndef DEBUG
+static inline
+#endif
+void pmap_decpteref __P((struct pmap *, struct pte *));
-vm_offset_t avail_start, avail_end;
-vm_offset_t virtual_avail, virtual_end; /* Available virtual memory */
+#ifndef PMAPDEBUG
+static inline
+#endif
+void rensa __P((int, struct pte *));
-/*
- * THIS INFORMATION IS OUTDATED. It's left here just inform curious people.
- *
- * badaddr() doesn't work on some VAXstations
- * (I've checked KA410 and KA43, don't know about others yet).
- *
- * Checking all pages of physical memory starting from address 0x0 and
- * waiting for being trapped by badaddr() is not enough on these machines:
- *
- * on VS2000/KA410 physical memory appears more than once.
- * eg. on a machine with 10MB memory (2MB base + 8MB extension)
- * the extension memory is mapped to 0x200000, 0xA00000, and so on.
- *
- * On VS3100/KA43 writing to addresses above the available memory
- * is implemented as a nop.
- *
- * On both of these machines the old check/count routine resulted in an
- * endless loop. Thus while checking/counting the memory, we write a
- * pattern to all the pages we are visiting. (leaving a hole for kernel).
- * If we access a page which already holds a valid pattern, then we've
- * seen this page already and thus reached the highest memory-address.
- * If the page doesn't hold the pattern directly after having written
- * it, then the page is bad or not available and we've reached the end.
- *
- * VAXen can't have more than 512(?) MB of physical memory, so we also
- * have an upper limit for how much pages to check. If we're not trapped
- * within this address-range, something went wrong and we're assuming
- * some save amount of physical memory. This might be paranoid, but...
- */
+vaddr_t avail_start, avail_end;
+vaddr_t virtual_avail, virtual_end; /* Available virtual memory */
+
+void pmap_pinit __P((pmap_t));
+void pmap_release __P((pmap_t));
+struct pv_entry *get_pventry __P((void));
+void free_pventry __P((struct pv_entry *));
+void more_pventries __P((void));
/*
* pmap_bootstrap().
void
pmap_bootstrap()
{
- unsigned int junk, sysptsize, istack;
- extern unsigned int proc0paddr, etext;
- extern struct vmspace vmspace0;
- struct pmap *p0pmap;
-
- p0pmap = &vmspace0.vm_pmap;
-
- /*
- * Machines older than MicroVAX II have their boot blocks
- * loaded directly or the boot program loaded from console
- * media, so we need to figure out their memory size.
- * This is not easily done on MicroVAXen, so we get it from
- * VMB instead.
- */
- if (avail_end == 0)
- while (badaddr((caddr_t)avail_end, 4) == 0)
- avail_end += NBPG * 128;
-
- avail_end = TRUNC_PAGE(avail_end); /* be sure */
+ unsigned int sysptsize, i;
+ extern unsigned int etext, proc0paddr;
+ struct pcb *pcb = (struct pcb *)proc0paddr;
+ pmap_t pmap = pmap_kernel();
/*
* Calculation of the System Page Table is somewhat a pain,
* Remember: sysptsize is in PTEs and nothing else!
*/
+#define USRPTSIZE ((MAXTSIZ + MAXDSIZ + MAXSSIZ + MMAPSPACE) / VAX_NBPG)
/* Kernel alloc area */
- sysptsize = (((0x100000 * maxproc) >> PGSHIFT) / 4);
+ sysptsize = (((0x100000 * maxproc) >> VAX_PGSHIFT) / 4);
/* reverse mapping struct */
- sysptsize += (avail_end >> PGSHIFT);
+ sysptsize += (avail_end >> VAX_PGSHIFT) * 2;
/* User Page table area. This may grow big */
-#define USRPTSIZE ((MAXTSIZ + MAXDSIZ + MAXSSIZ + MMAPSPACE) / NBPG)
- sysptsize += ((USRPTSIZE * 4) / NBPG) * maxproc;
+ sysptsize += ((USRPTSIZE * 4) / VAX_NBPG) * maxproc;
/* Kernel stacks per process */
sysptsize += UPAGES * maxproc;
- /* Buffer cache */
- sysptsize += bufcalc() * CLSIZE;
- /* mbufs */
- sysptsize += VM_MBUF_SIZE / NBPG;
- /* physio space */
- sysptsize += VM_PHYS_SIZE / NBPG;
+ /* IO device register space */
+ sysptsize += IOSPSZ;
/*
* Virtual_* and avail_* is used for mapping of system page table.
- * First set them to their max values and then decrement them.
* The need for kernel virtual memory is linear dependent of the
* amount of physical memory also, therefore sysptsize is
* a variable here that is changed dependent of the physical
* memory size.
*/
- virtual_avail = KERNBASE;
- virtual_end = KERNBASE + sysptsize * NBPG;
- avail_start = 0;
- blkclr(Sysmap, sysptsize * 4); /* clear SPT before using it */
+ virtual_avail = avail_end + KERNBASE;
+ virtual_end = KERNBASE + sysptsize * VAX_NBPG;
+ memset(Sysmap, 0, sysptsize * 4); /* clear SPT before using it */
+
+ /*
+ * The first part of Kernel Virtual memory is the physical
+ * memory mapped in. This makes some mm routines both simpler
+ * and faster, but takes ~0.75% more memory.
+ */
+ pmap_map(KERNBASE, 0, avail_end, VM_PROT_READ|VM_PROT_WRITE);
/*
- * Map kernel. Kernel code is always readable for user,
- * it must be because of the emulation code that is somewhere
- * in there. And it doesn't hurt, kernel is also public readable.
+ * Kernel code is always readable for user, it must be because
+ * of the emulation code that is somewhere in there.
+ * And it doesn't hurt, /netbsd is also public readable.
* There are also a couple of other things that must be in
* physical memory and that isn't managed by the vm system.
*/
-#ifdef DDB
- MAPPHYS(junk, btoc(ROUND_PAGE(&etext) - KERNBASE),
- VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
-#else
- MAPPHYS(junk, btoc(ROUND_PAGE(&etext) - KERNBASE), VM_PROT_EXECUTE);
-#endif
- MAPPHYS(junk, btoc((u_int)Sysmap - ROUND_PAGE(&etext)),
- VM_PROT_READ|VM_PROT_WRITE);
+ for (i = 0; i < ((unsigned)&etext - KERNBASE) >> VAX_PGSHIFT; i++)
+ Sysmap[i].pg_prot = PROT_URKW;
/* Map System Page Table and zero it, Sysmap already set. */
- mtpr(avail_start, PR_SBR);
- MAPPHYS(junk, btoc(ROUND_PAGE(sysptsize * 4)),
- VM_PROT_READ|VM_PROT_WRITE);
+ mtpr((unsigned)Sysmap - KERNBASE, PR_SBR);
/* Map Interrupt stack and set red zone */
- MAPPHYS(istack, btoc(ISTACK_SIZE), VM_PROT_READ|VM_PROT_WRITE);
+ istack = (unsigned)Sysmap + ROUND_PAGE(sysptsize * 4);
mtpr(istack + ISTACK_SIZE, PR_ISP);
kvtopte(istack)->pg_v = 0;
- /* Take four pages for scratch use */
- MAPPHYS(scratch, 4, VM_PROT_READ|VM_PROT_WRITE);
-
- /* Kernel message buffer */
- MAPPHYS(msgbufp, btoc(ROUND_PAGE(sizeof(struct msgbuf))),
- VM_PROT_READ|VM_PROT_WRITE);
+ /* Some scratch pages */
+ scratch = (void *)((u_int)istack + ISTACK_SIZE);
/* Physical-to-virtual translation table */
- MAPPHYS(pv_table, btoc((avail_end / PAGE_SIZE ) *
- sizeof(struct pv_entry)), VM_PROT_READ|VM_PROT_WRITE);
+ (unsigned)pv_table = (u_int)scratch + 4 * VAX_NBPG;
+
+ avail_start = (unsigned)pv_table + (ROUND_PAGE(avail_end >> PGSHIFT)) *
+ sizeof(struct pv_entry) - KERNBASE;
+
+ /* Kernel message buffer */
+ avail_end -= MSGBUFSIZE;
+ msgbufp = (void *)(avail_end + KERNBASE);
+ msgbufp->msg_magic = MSG_MAGIC-1; /* ensure that it will be zeroed */
/* zero all mapped physical memory from Sysmap to here */
- blkclr((void *)istack, (avail_start | 0x80000000) - istack);
+ memset((void *)istack, 0, (avail_start + KERNBASE) - istack);
- /* Now map up what is only needed in virtual memory. */
- MAPVIRT(vmmap, 2);
- (pt_entry_t *)pte_cmap = kvtopte(vmmap);
+ /* Set logical page size */
+ uvmexp.pagesize = NBPG;
+ uvm_setpagesize();
+
+ /* QDSS console mapping hack */
+#if NQD > 0
+ qdearly();
+#endif
+
+ /* User page table map. This is big. */
+ MAPVIRT(ptemapstart, USRPTSIZE);
+ ptemapend = virtual_avail;
+
+ MAPVIRT(iospace, IOSPSZ); /* Device iospace mapping area */
+
+ /* Init SCB and set up stray vectors. */
+ avail_start = scb_init(avail_start);
+ bzero(0, VAX_NBPG >> 1);
+
+ if (dep_call->cpu_steal_pages)
+ (*dep_call->cpu_steal_pages)();
- /*
- * We move SCB here from physical address 0 to an address
- * somewhere else, so that we can dynamically allocate
- * space for interrupt vectors and other machine-specific
- * things. We move it here, but the rest of the allocation
- * is done in a cpu-specific routine.
- * avail_start is modified in the cpu-specific routine.
- */
- scb = (struct scb *)virtual_avail;
- bcopy(0, (void *)avail_start, NBPG >> 1);
- mtpr(avail_start, PR_SCBB);
- bzero(0, NBPG >> 1);
- (*dep_call->cpu_steal_pages)();
avail_start = ROUND_PAGE(avail_start);
virtual_avail = ROUND_PAGE(virtual_avail);
+ virtual_end = TRUNC_PAGE(virtual_end);
-#ifdef PMAPDEBUG
- printf("Sysmap %x, istack %x, scratch %x\n",Sysmap,istack,scratch);
- printf("etext %x\n", &etext);
+
+#if 0 /* Breaks cninit() on some machines */
+ cninit();
+ printf("Sysmap %p, istack %lx, scratch %p\n",Sysmap,istack,scratch);
+ printf("etext %p\n", &etext);
printf("SYSPTSIZE %x\n",sysptsize);
- printf("pv_table %x, vmmap %x, pte_cmap %x\n",
- pv_table,vmmap,pte_cmap);
- printf("avail_start %x, avail_end %x\n",avail_start,avail_end);
- printf("virtual_avail %x,virtual_end %x\n",virtual_avail,virtual_end);
- printf("clearomr: %x \n",(uint)vmmap-(uint)Sysmap);
-/* printf("faultdebug %x, startsysc %x\n",&faultdebug, &startsysc);*/
- printf("startpmapdebug %x\n",&startpmapdebug);
+ printf("pv_table %p, ptemapstart %lx ptemapend %lx\n",
+ pv_table, ptemapstart, ptemapend);
+ printf("avail_start %lx, avail_end %lx\n",avail_start,avail_end);
+ printf("virtual_avail %lx,virtual_end %lx\n",
+ virtual_avail, virtual_end);
+ printf("startpmapdebug %p\n",&startpmapdebug);
#endif
/* Init kernel pmap */
- pmap_kernel()->ref_count = 1;
- simple_lock_init(&pmap_kernel()->pm_lock);
- p0pmap->pm_pcb = (struct pcb *)proc0paddr;
-
- p0pmap->pm_pcb->P1BR = (void *)0x80000000;
- p0pmap->pm_pcb->P0BR = (void *)0x80000000;
- p0pmap->pm_pcb->P1LR = 0x200000;
- p0pmap->pm_pcb->P0LR = AST_PCB;
- mtpr(0x80000000, PR_P1BR);
- mtpr(0x80000000, PR_P0BR);
- mtpr(0x200000, PR_P1LR);
- mtpr(AST_PCB, PR_P0LR);
+ pmap->pm_p1br = (void *)KERNBASE;
+ pmap->pm_p0br = (void *)KERNBASE;
+ pmap->pm_p1lr = 0x200000;
+ pmap->pm_p0lr = AST_PCB;
+ pmap->pm_stats.wired_count = pmap->pm_stats.resident_count = 0;
+ /* btop(virtual_avail - KERNBASE); */
+
+ pmap->ref_count = 1;
+
+ /* Activate the kernel pmap. */
+ mtpr(pcb->P1BR = pmap->pm_p1br, PR_P1BR);
+ mtpr(pcb->P0BR = pmap->pm_p0br, PR_P0BR);
+ mtpr(pcb->P1LR = pmap->pm_p1lr, PR_P1LR);
+ mtpr(pcb->P0LR = pmap->pm_p0lr, PR_P0LR);
+
/*
* Now everything should be complete, start virtual memory.
*/
+ uvm_page_physload(avail_start >> PGSHIFT, avail_end >> PGSHIFT,
+ avail_start >> PGSHIFT, avail_end >> PGSHIFT,
+ VM_FREELIST_DEFAULT);
mtpr(sysptsize, PR_SLR);
mtpr(1, PR_MAPEN);
}
+/*
+ * Let the VM system do early memory allocation from the direct-mapped
+ * physical memory instead.
+ */
+vaddr_t
+pmap_steal_memory(size, vstartp, vendp)
+ vsize_t size;
+ vaddr_t *vstartp, *vendp;
+{
+ vaddr_t v;
+ int npgs;
+
+#ifdef PMAPDEBUG
+ if (startpmapdebug)
+ printf("pmap_steal_memory: size 0x%lx start %p end %p\n",
+ size, vstartp, vendp);
+#endif
+ size = round_page(size);
+ npgs = btoc(size);
+
+ /*
+ * A vax only have one segment of memory.
+ */
+#ifdef DIAGNOSTIC
+ if (vm_physmem[0].pgs)
+ panic("pmap_steal_memory: called _after_ bootstrap");
+#endif
+
+ v = (vm_physmem[0].avail_start << PGSHIFT) | KERNBASE;
+ vm_physmem[0].avail_start += npgs;
+ vm_physmem[0].start += npgs;
+ if (vstartp)
+ *vstartp = virtual_avail;
+ if (vendp)
+ *vendp = virtual_end;
+ bzero((caddr_t)v, size);
+ return v;
+}
/*
* pmap_init() is called as part of vm init after memory management
* is enabled. It is meant to do machine-specific allocations.
- * Here we allocate virtual memory for user page tables.
+ * Here is the resource map for the user page tables inited.
*/
void
-pmap_init(start, end)
- vm_offset_t start, end;
+pmap_init()
{
- vm_offset_t ptemapstart,ptemapend;
-
- /* reserve place on SPT for UPT */
- pte_map = kmem_suballoc(kernel_map, &ptemapstart, &ptemapend,
- USRPTSIZE * 4 * maxproc, TRUE);
+ /*
+ * Create the extent map used to manage the page table space.
+ * XXX - M_HTABLE is bogus.
+ */
+ ptemap = extent_create("ptemap", ptemapstart, ptemapend,
+ M_HTABLE, ptmapstorage, PTMAPSZ, EX_NOCOALESCE);
+ if (ptemap == NULL)
+ panic("pmap_init");
}
+/*
+ * Decrement a reference to a pte page. If all references are gone,
+ * free the page.
+ */
+void
+pmap_decpteref(pmap, pte)
+ struct pmap *pmap;
+ struct pte *pte;
+{
+ paddr_t paddr;
+ int index;
+
+ if (pmap == pmap_kernel())
+ return;
+ index = ((vaddr_t)pte - (vaddr_t)pmap->pm_p0br) >> PGSHIFT;
+
+ pte = (struct pte *)trunc_page(pte);
+#ifdef PMAPDEBUG
+ if (startpmapdebug)
+ printf("pmap_decpteref: pmap %p pte %p index %d refcnt %d\n",
+ pmap, pte, index, pmap->pm_refcnt[index]);
+#endif
+
+#ifdef DEBUG
+ if ((index < 0) || (index >= NPTEPGS))
+ panic("pmap_decpteref: bad index %d", index);
+#endif
+ pmap->pm_refcnt[index]--;
+#ifdef DEBUG
+ if (pmap->pm_refcnt[index] >= VAX_NBPG/sizeof(struct pte))
+ panic("pmap_decpteref");
+#endif
+ if (pmap->pm_refcnt[index] == 0) {
+ paddr = kvtopte(pte)->pg_pfn << VAX_PGSHIFT;
+ uvm_pagefree(PHYS_TO_VM_PAGE(paddr));
+ bzero(kvtopte(pte), sizeof(struct pte) * LTOHPN);
+ }
+}
/*
* pmap_create() creates a pmap for a new task.
* If not already allocated, malloc space for one.
*/
-pmap_t
-pmap_create(phys_size)
- vm_size_t phys_size;
+struct pmap *
+pmap_create()
+{
+ struct pmap *pmap;
+
+ MALLOC(pmap, struct pmap *, sizeof(*pmap), M_VMPMAP, M_WAITOK);
+ bzero(pmap, sizeof(struct pmap));
+ pmap_pinit(pmap);
+ return(pmap);
+}
+
+/*
+ * Initialize a preallocated an zeroed pmap structure,
+ */
+void
+pmap_pinit(pmap)
+ pmap_t pmap;
{
- pmap_t pmap;
+ int bytesiz, res;
+
+ /*
+ * Allocate PTEs and stash them away in the pmap.
+ * XXX Ok to use kmem_alloc_wait() here?
+ */
+ bytesiz = USRPTSIZE * sizeof(struct pte);
+ res = extent_alloc(ptemap, bytesiz, 4, 0, EX_WAITSPACE|EX_WAITOK,
+ (u_long *)&pmap->pm_p0br);
+ if (res)
+ panic("pmap_pinit");
+ pmap->pm_p0lr = vax_btoc(MAXTSIZ + MAXDSIZ + MMAPSPACE) | AST_PCB;
+ (vaddr_t)pmap->pm_p1br = (vaddr_t)pmap->pm_p0br + bytesiz - 0x800000;
+ pmap->pm_p1lr = (0x200000 - vax_btoc(MAXSSIZ));
+ pmap->pm_stack = USRSTACK;
#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_create: phys_size %x\n",phys_size);
+if (startpmapdebug)
+ printf("pmap_pinit(%p): p0br=%p p0lr=0x%lx p1br=%p p1lr=0x%lx\n",
+ pmap, pmap->pm_p0br, pmap->pm_p0lr, pmap->pm_p1br, pmap->pm_p1lr);
#endif
- if (phys_size)
- return NULL;
-
- pmap = (pmap_t) malloc(sizeof(struct pmap), M_VMPMAP, M_WAITOK);
- pmap_pinit(pmap);
- return (pmap);
+ pmap->ref_count = 1;
+ pmap->pm_stats.resident_count = pmap->pm_stats.wired_count = 0;
}
-
/*
* Release any resources held by the given physical map.
* Called when a pmap initialized by pmap_pinit is being released.
pmap_release(pmap)
struct pmap *pmap;
{
-#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_release: pmap %x\n",pmap);
+#ifdef DEBUG
+ vaddr_t saddr, eaddr;
+ int i;
#endif
- if (pmap->pm_pcb->P0BR)
- kmem_free_wakeup(pte_map, (vm_offset_t)pmap->pm_pcb->P0BR,
- (pmap->pm_pcb->P0LR & ~AST_MASK) * 4);
+#ifdef PMAPDEBUG
+if(startpmapdebug)printf("pmap_release: pmap %p\n",pmap);
+#endif
- if (pmap->pm_pcb->P1BR)
- kmem_free_wakeup(pte_map, (vm_offset_t)pmap->pm_stack,
- (0x200000 - pmap->pm_pcb->P1LR) * 4);
+ if (pmap->pm_p0br == 0)
+ return;
- bzero(pmap, sizeof(struct pmap));
+#ifdef DEBUG
+ for (i = 0; i < NPTEPGS; i++)
+ if (pmap->pm_refcnt[i])
+ panic("pmap_release: refcnt %d index %d",
+ pmap->pm_refcnt[i], i);
+
+ saddr = (vaddr_t)pmap->pm_p0br;
+ eaddr = saddr + USRPTSIZE * sizeof(struct pte);
+ for (; saddr < eaddr; saddr += NBPG)
+ if (kvtopte(saddr)->pg_pfn)
+ panic("pmap_release: page mapped");
+#endif
+ extent_free(ptemap, (u_long)pmap->pm_p0br,
+ USRPTSIZE * sizeof(struct pte), EX_WAITOK);
+ mtpr(0, PR_TBIA);
}
+void
+pmap_change_wiring(pmap, va, wired)
+ register pmap_t pmap;
+ vaddr_t va;
+ boolean_t wired;
+{
+ int *p, *pte, i;
+
+ if (va & KERNBASE) {
+ p = (int *)Sysmap;
+ i = (va - KERNBASE) >> VAX_PGSHIFT;
+ } else {
+ if(va < 0x40000000) {
+ p = (int *)pmap->pm_p0br;
+ i = va >> VAX_PGSHIFT;
+ } else {
+ p = (int *)pmap->pm_p1br;
+ i = (va - 0x40000000) >> VAX_PGSHIFT;
+ }
+ }
+ pte = &p[i];
+
+ if(wired)
+ *pte |= PG_W;
+ else
+ *pte &= ~PG_W;
+}
/*
* pmap_destroy(pmap): Remove a reference from the pmap.
int count;
#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_destroy: pmap %x\n",pmap);
+if(startpmapdebug)printf("pmap_destroy: pmap %p\n",pmap);
#endif
if (pmap == NULL)
return;
count = --pmap->ref_count;
simple_unlock(&pmap->pm_lock);
- if (!count) {
+ if (count == 0) {
pmap_release(pmap);
- free((caddr_t)pmap, M_VMPMAP);
+ FREE((caddr_t)pmap, M_VMPMAP);
}
}
-void
-pmap_enter(pmap, v, p, prot, wired)
- register pmap_t pmap;
- vm_offset_t v;
- vm_offset_t p;
- vm_prot_t prot;
- boolean_t wired;
+/*
+ * Rensa is a help routine to remove a pv_entry from the pv list.
+ * Arguments are physical clustering page and page table entry pointer.
+ */
+void
+rensa(clp, ptp)
+ int clp;
+ struct pte *ptp;
{
- u_int i, pte, s, *patch;
- pv_entry_t pv, tmp;
+ struct pv_entry *pf, *pl, *pv = pv_table + clp;
+ int s, *g;
- if (v > 0x7fffffff) pte = kernel_prot[prot] | PG_PFNUM(p) | PG_V;
- else pte = prot_array[prot] | PG_PFNUM(p) | PG_V;
+#ifdef PMAPDEBUG
+if (startpmapdebug)
+ printf("rensa: pv %p clp 0x%x ptp %p\n", pv, clp, ptp);
+#endif
s = splimp();
- pv = PHYS_TO_PV(p);
+ RECURSESTART;
+ if (pv->pv_pte == ptp) {
+ g = (int *)pv->pv_pte;
+ if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
+ pv->pv_attr |= g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
+ pv->pv_pte = 0;
+ pv->pv_pmap->pm_stats.resident_count--;
+ pv->pv_pmap = 0;
+ splx(s);
+ RECURSEEND;
+ return;
+ }
+ for (pl = pv; pl->pv_next; pl = pl->pv_next) {
+ if (pl->pv_next->pv_pte == ptp) {
+ pf = pl->pv_next;
+ pl->pv_next = pl->pv_next->pv_next;
+ g = (int *)pf->pv_pte;
+ if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
+ pv->pv_attr |=
+ g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
+ pf->pv_pmap->pm_stats.resident_count--;
+ free_pventry(pf);
+ splx(s);
+ RECURSEEND;
+ return;
+ }
+ }
+ panic("rensa");
+}
+
+/*
+ * New (real nice!) function that allocates memory in kernel space
+ * without tracking it in the MD code.
+ */
+void
+pmap_kenter_pa(va, pa, prot)
+ vaddr_t va;
+ paddr_t pa;
+ vm_prot_t prot;
+{
+ int *ptp;
+ ptp = (int *)kvtopte(va);
#ifdef PMAPDEBUG
if(startpmapdebug)
-printf("pmap_enter: pmap: %x,virt %x, phys %x,pv %x prot %x\n",
- pmap,v,p,pv,prot);
+ printf("pmap_kenter_pa: va: %lx, pa %lx, prot %x ptp %p\n", va, pa, prot, ptp);
#endif
- if (!pmap) return;
- if (wired) pte |= PG_W;
-
-
- if (v < 0x40000000) {
- patch = (int *)pmap->pm_pcb->P0BR;
- i = (v >> PGSHIFT);
- if (i >= (pmap->pm_pcb->P0LR&~AST_MASK))
- pmap_expandp0(pmap, i);
- patch = (int *)pmap->pm_pcb->P0BR;
- } else if (v < (u_int)0x80000000) {
- patch = (int *)pmap->pm_pcb->P1BR;
- i = (v - 0x40000000) >> PGSHIFT;
- if (i < pmap->pm_pcb->P1LR)
- panic("pmap_enter: must expand P1");
- } else {
+ ptp[0] = PG_V | ((prot & VM_PROT_WRITE)? PG_KW : PG_KR) |
+ PG_PFNUM(pa) | PG_SREF;
+ ptp[1] = ptp[0] + 1;
+ ptp[2] = ptp[0] + 2;
+ ptp[3] = ptp[0] + 3;
+ ptp[4] = ptp[0] + 4;
+ ptp[5] = ptp[0] + 5;
+ ptp[6] = ptp[0] + 6;
+ ptp[7] = ptp[0] + 7;
+ mtpr(0, PR_TBIA);
+}
+
+void
+pmap_kremove(va, len)
+ vaddr_t va;
+ vsize_t len;
+{
+ struct pte *pte;
+ int i;
+
+#ifdef PMAPDEBUG
+if(startpmapdebug)
+ printf("pmap_kremove: va: %lx, len %lx, ptp %p\n", va, len, kvtopte(va));
+#endif
+
+ /*
+ * Unfortunately we must check if any page may be on the pv list.
+ */
+ pte = kvtopte(va);
+ len >>= PGSHIFT;
+
+ for (i = 0; i < len; i++) {
+ if (pte->pg_pfn == 0)
+ continue;
+ if (pte->pg_sref == 0)
+ rensa(pte->pg_pfn >> LTOHPS, pte);
+ bzero(pte, LTOHPN * sizeof(struct pte));
+ pte += LTOHPN;
+ }
+ mtpr(0, PR_TBIA);
+}
+
+void
+pmap_kenter_pgs(va, pgs, npgs)
+ vaddr_t va;
+ struct vm_page **pgs;
+ int npgs;
+{
+ int i;
+ int *ptp;
+
+#ifdef PMAPDEBUG
+if(startpmapdebug)
+ printf("pmap_kenter_pgs: va: %lx, pgs %p, npgs %x\n", va, pgs, npgs);
+#endif
+
+ /*
+ * May this routine affect page tables?
+ * We assume that, and uses TBIA.
+ */
+ ptp = (int *)kvtopte(va);
+ for (i = 0 ; i < npgs ; i++) {
+ ptp[0] = PG_V | PG_KW |
+ PG_PFNUM(VM_PAGE_TO_PHYS(pgs[i])) | PG_SREF;
+ ptp[1] = ptp[0] + 1;
+ ptp[2] = ptp[0] + 2;
+ ptp[3] = ptp[0] + 3;
+ ptp[4] = ptp[0] + 4;
+ ptp[5] = ptp[0] + 5;
+ ptp[6] = ptp[0] + 6;
+ ptp[7] = ptp[0] + 7;
+ ptp += LTOHPN;
+ }
+ mtpr(0, PR_TBIA);
+}
+
+/*
+ * pmap_enter() is the main routine that puts in mappings for pages, or
+ * upgrades mappings to more "rights". Note that:
+ */
+void
+pmap_enter(pmap, v, p, prot, wired, access_type)
+ pmap_t pmap;
+ vaddr_t v;
+ paddr_t p;
+ vm_prot_t prot;
+ boolean_t wired;
+ vm_prot_t access_type;
+{
+ struct pv_entry *pv, *tmp;
+ int i, s, newpte, oldpte, *patch, index = 0; /* XXX gcc */
+
+#ifdef PMAPDEBUG
+if (startpmapdebug)
+ printf("pmap_enter: pmap %p v %lx p %lx prot %x wired %d access %x\n",
+ pmap, v, p, prot, wired, access_type & VM_PROT_ALL);
+#endif
+ /* Can this happen with UVM??? */
+ if (pmap == 0)
+ return;
+
+ RECURSESTART;
+ /* Find addess of correct pte */
+ if (v & KERNBASE) {
patch = (int *)Sysmap;
- i = (v - (u_int)0x80000000) >> PGSHIFT;
+ i = (v - KERNBASE) >> VAX_PGSHIFT;
+ newpte = (p>>VAX_PGSHIFT)|(prot&VM_PROT_WRITE?PG_KW:PG_KR);
+ } else {
+ if (v < 0x40000000) {
+ patch = (int *)pmap->pm_p0br;
+ i = (v >> VAX_PGSHIFT);
+ if (i >= (pmap->pm_p0lr & ~AST_MASK))
+ panic("P0 too small in pmap_enter");
+ patch = (int *)pmap->pm_p0br;
+ newpte = (p >> VAX_PGSHIFT) |
+ (prot & VM_PROT_WRITE ? PG_RW : PG_RO);
+ } else {
+ patch = (int *)pmap->pm_p1br;
+ i = (v - 0x40000000) >> VAX_PGSHIFT;
+ if (i < pmap->pm_p1lr)
+ panic("pmap_enter: must expand P1");
+ if (v < pmap->pm_stack)
+ pmap->pm_stack = v;
+ newpte = (p >> VAX_PGSHIFT) |
+ (prot & VM_PROT_WRITE ? PG_RW : PG_RO);
+ }
+
+ /*
+ * Check if a pte page must be mapped in.
+ */
+ index = ((u_int)&patch[i] - (u_int)pmap->pm_p0br) >> PGSHIFT;
+#ifdef DIAGNOSTIC
+ if ((index < 0) || (index >= NPTEPGS))
+ panic("pmap_enter: bad index %d", index);
+#endif
+ if (pmap->pm_refcnt[index] == 0) {
+ vaddr_t ptaddr = trunc_page(&patch[i]);
+ paddr_t phys;
+ struct vm_page *pg;
+#ifdef DEBUG
+ if (kvtopte(&patch[i])->pg_pfn)
+ panic("pmap_enter: refcnt == 0");
+#endif
+ /*
+ * It seems to be legal to sleep here to wait for
+ * pages; at least some other ports do so.
+ */
+ for (;;) {
+ pg = uvm_pagealloc(NULL, 0, NULL, 0);
+ if (pg != NULL)
+ break;
+
+ if (pmap == pmap_kernel())
+ panic("pmap_enter: no free pages");
+ else
+ uvm_wait("pmap_enter");
+ }
+
+ phys = VM_PAGE_TO_PHYS(pg);
+ bzero((caddr_t)(phys|KERNBASE), NBPG);
+ pmap_kenter_pa(ptaddr, phys,
+ VM_PROT_READ|VM_PROT_WRITE);
+ }
}
- if ((patch[i] & PG_FRAME) == (pte & PG_FRAME)) { /* no map change */
- if ((patch[i] & PG_W) != (pte & PG_W)) { /* wiring change */
- pmap_change_wiring(pmap, v, wired);
- } else if ((patch[i] & PG_PROT) != (pte & PG_PROT)) {
- patch[i] &= ~PG_PROT;
- patch[i++] |= prot_array[prot];
- patch[i] &= ~PG_PROT;
- patch[i] |= prot_array[prot];
- mtpr(v, PR_TBIS);
- mtpr(v + NBPG, PR_TBIS);
- } else if ((patch[i] & PG_V) == 0) {
- if (patch[i] & PG_SREF) {
- patch[i] &= ~PG_SREF;
- patch[i] |= PG_V | PG_REF;
- } else patch[i] |= PG_V;
- if (patch[++i] & PG_SREF) {
- patch[i] &= ~PG_SREF;
- patch[i] |= PG_V | PG_REF;
- } else patch[i] |= PG_V;
- mtpr(v, PR_TBIS);
- mtpr(v + NBPG, PR_TBIS);
- } /* else nothing to do */
- splx(s);
+ oldpte = patch[i] & ~(PG_V|PG_M);
+
+ /* No mapping change. Can this happen??? */
+ if (newpte == oldpte) {
+ RECURSEEND;
return;
}
- if (!pv->pv_pmap) {
- pv->pv_pmap = pmap;
- pv->pv_next = NULL;
- pv->pv_va = v;
+ pv = pv_table + (p >> PGSHIFT);
+
+ /* Changing mapping? */
+ oldpte &= PG_FRAME;
+ if ((newpte & PG_FRAME) != oldpte) {
+
+ /*
+ * Mapped before? Remove it then.
+ */
+ if (oldpte) {
+ RECURSEEND;
+ rensa(oldpte >> LTOHPS, (struct pte *)&patch[i]);
+ RECURSESTART;
+ } else if (pmap != pmap_kernel())
+ pmap->pm_refcnt[index]++; /* New mapping */
+
+ s = splimp();
+ if (pv->pv_pte == 0) {
+ pv->pv_pte = (struct pte *) & patch[i];
+ pv->pv_pmap = pmap;
+ } else {
+ tmp = get_pventry();
+ tmp->pv_pte = (struct pte *)&patch[i];
+ tmp->pv_pmap = pmap;
+ tmp->pv_next = pv->pv_next;
+ pv->pv_next = tmp;
+ }
+ splx(s);
} else {
- tmp = alloc_pv_entry();
- tmp->pv_pmap = pmap;
- tmp->pv_next = pv->pv_next;
- tmp->pv_va = v;
- pv->pv_next = tmp;
+ /* No mapping change, just flush the TLB */
+ mtpr(0, PR_TBIA);
}
- patch[i++] = pte++;
- patch[i] = pte;
- mtpr(v, PR_TBIS);
- mtpr(v + NBPG, PR_TBIS);
- splx(s);
+ pmap->pm_stats.resident_count++;
+
+ if (access_type & VM_PROT_READ) {
+ pv->pv_attr |= PG_V;
+ newpte |= PG_V;
+ }
+ if (access_type & VM_PROT_WRITE)
+ pv->pv_attr |= PG_M;
+
+ patch[i] = newpte;
+ patch[i+1] = newpte+1;
+ patch[i+2] = newpte+2;
+ patch[i+3] = newpte+3;
+ patch[i+4] = newpte+4;
+ patch[i+5] = newpte+5;
+ patch[i+6] = newpte+6;
+ patch[i+7] = newpte+7;
+ RECURSEEND;
+#ifdef DEBUG
+ if (pmap != pmap_kernel())
+ if (pmap->pm_refcnt[index] > VAX_NBPG/sizeof(struct pte))
+ panic("pmap_enter: refcnt %d", pmap->pm_refcnt[index]);
+#endif
+ if (pventries < 10)
+ more_pventries();
+
+ return;
}
void *
#ifdef PMAPDEBUG
if(startpmapdebug)
-printf("pmap_bootstrap_alloc: size 0x %x\n",size);
+ printf("pmap_bootstrap_alloc: size 0x %x\n",size);
#endif
size = round_page(size);
- mem = (void *)virtual_avail;
- virtual_avail = pmap_map(virtual_avail, avail_start,
- avail_start + size, VM_PROT_READ|VM_PROT_WRITE);
+ mem = (caddr_t)avail_start + KERNBASE;
avail_start += size;
- blkclr(mem, size);
+ memset(mem, 0, size);
return (mem);
}
-vm_offset_t
+vaddr_t
pmap_map(virtuell, pstart, pend, prot)
- vm_offset_t virtuell, pstart, pend;
+ vaddr_t virtuell;
+ paddr_t pstart, pend;
int prot;
{
- vm_offset_t count;
+ vaddr_t count;
int *pentry;
#ifdef PMAPDEBUG
if(startpmapdebug)
- printf("pmap_map: virt %x, pstart %x, pend %x, Sysmap %x\n",
+ printf("pmap_map: virt %lx, pstart %lx, pend %lx, Sysmap %p\n",
virtuell, pstart, pend, Sysmap);
#endif
pstart=(uint)pstart &0x7fffffff;
pend=(uint)pend &0x7fffffff;
virtuell=(uint)virtuell &0x7fffffff;
- (uint)pentry= (((uint)(virtuell)>>PGSHIFT)*4)+(uint)Sysmap;
- for(count=pstart;count<pend;count+=NBPG){
- *pentry++ = (count>>PGSHIFT)|kernel_prot[prot]|PG_V;
+ (uint)pentry= (((uint)(virtuell)>>VAX_PGSHIFT)*4)+(uint)Sysmap;
+ for(count=pstart;count<pend;count+=VAX_NBPG){
+ *pentry++ = (count>>VAX_PGSHIFT)|PG_V|
+ (prot & VM_PROT_WRITE ? PG_KW : PG_KR);
}
mtpr(0,PR_TBIA);
- return(virtuell+(count-pstart)+0x80000000);
+ return(virtuell+(count-pstart)+KERNBASE);
}
-vm_offset_t
+paddr_t
pmap_extract(pmap, va)
pmap_t pmap;
- vm_offset_t va;
+ vaddr_t va;
{
+ paddr_t pa = 0;
+ int *pte, sva;
- int *pte;
#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_extract: pmap %x, va %x\n",pmap, va);
+if(startpmapdebug)printf("pmap_extract: pmap %p, va %lx\n",pmap, va);
#endif
- pte=(int *)pmap_virt2pte(pmap,va);
- if(pte) return(((*pte&PG_FRAME)<<PGSHIFT)+((u_int)va&PGOFSET));
- else return 0;
-}
-
-/*
- * pmap_protect( pmap, vstart, vend, protect)
- */
-void
-pmap_protect(pmap, start, end, prot)
- pmap_t pmap;
- vm_offset_t start;
- vm_offset_t end;
- vm_prot_t prot;
-{
- int pte, *patch, s;
-
-#ifdef PMAPDEBUG
-if(startpmapdebug) printf("pmap_protect: pmap %x, start %x, end %x, prot %x\n",
- pmap, start, end,prot);
-#endif
- if(pmap==NULL) return;
- s=splimp();
- if(start>0x7fffffff) pte=kernel_prot[prot];
- else pte=prot_array[prot];
-
- if(end<0x40000000){
- while((end>>PGSHIFT)>(pmap->pm_pcb->P0LR&~AST_MASK))
- pmap_expandp0(pmap,(end>>PGSHIFT));
- } else if(end<(u_int)0x80000000){
- u_int i;
- i=(start&0x3fffffff)>>PGSHIFT;
- if(i<pmap->pm_pcb->P1LR)
- start=((pmap->pm_pcb->P1LR)<<PGSHIFT)+0x40000000;
- i=(end&0x3fffffff)>>PGSHIFT;
- if(i<pmap->pm_pcb->P1LR) return;
+ if (va & KERNBASE) {
+ pa = kvtophys(va); /* Is 0 if not mapped */
+ return(pa);
}
- while (start < end) {
- patch = (int *)pmap_virt2pte(pmap,start);
- if(patch){
- *patch&=(~PG_PROT);
- *patch|=pte;
- mtpr(start,PR_TBIS);
- }
- start += NBPG;
+
+ sva = PG_PFNUM(va);
+ if (va < 0x40000000) {
+ if (sva > (pmap->pm_p0lr & ~AST_MASK))
+ return NULL;
+ pte = (int *)pmap->pm_p0br;
+ } else {
+ if (sva < pmap->pm_p1lr)
+ return NULL;
+ pte = (int *)pmap->pm_p1br;
}
- mtpr(0,PR_TBIA);
- splx(s);
+ if (kvtopte(&pte[sva])->pg_pfn)
+ return ((pte[sva] & PG_FRAME) << VAX_PGSHIFT);
+
+ return (NULL);
}
/*
- * pmap_remove(pmap, start, slut) removes all valid mappings between
- * the two virtual adresses start and slut from pmap pmap.
- * NOTE: all adresses between start and slut may not be mapped.
+ * Sets protection for a given region to prot. If prot == none then
+ * unmap region. pmap_remove is implemented as pmap_protect with
+ * protection none.
*/
-
void
-pmap_remove(pmap, start, slut)
+pmap_protect(pmap, start, end, prot)
pmap_t pmap;
- vm_offset_t start, slut;
+ vaddr_t start, end;
+ vm_prot_t prot;
{
- u_int *ptestart, *pteslut, s, *temp;
- pv_entry_t pv;
- vm_offset_t countup;
+ struct pte *pt, *pts, *ptd;
+ int pr;
#ifdef PMAPDEBUG
-if(startpmapdebug) printf("pmap_remove: pmap=0x %x, start=0x %x, slut=0x %x\n",
- pmap, start, slut);
+if(startpmapdebug) printf("pmap_protect: pmap %p, start %lx, end %lx, prot %x\n",
+ pmap, start, end,prot);
#endif
- if (!pmap)
+ if (pmap == 0)
return;
- if(!pmap->pm_pcb&&start<0x80000000) return; /* No page registers */
-/* First, get pte first address */
- if(start<0x40000000){ /* P0 */
- if (!(temp = (unsigned *)pmap->pm_pcb->P0BR))
- return; /* No page table */
- ptestart=&temp[start>>PGSHIFT];
- pteslut=&temp[slut>>PGSHIFT];
- if(pteslut>&temp[(pmap->pm_pcb->P0LR&~AST_MASK)])
- pteslut=&temp[(pmap->pm_pcb->P0LR&~AST_MASK)];
- } else if(start>0x7fffffff){ /* System region */
- ptestart=(u_int *)&Sysmap[(start&0x3fffffff)>>PGSHIFT];
- pteslut=(u_int *)&Sysmap[(slut&0x3fffffff)>>PGSHIFT];
- } else { /* P1 (stack) region */
- if (!(temp = (unsigned *)pmap->pm_pcb->P1BR))
- return; /* No page table */
- pteslut=&temp[(slut&0x3fffffff)>>PGSHIFT];
- ptestart=&temp[(start&0x3fffffff)>>PGSHIFT];
- if(ptestart<&temp[pmap->pm_pcb->P1LR])
- ptestart=&temp[pmap->pm_pcb->P1LR];
- }
-#ifdef PMAPDEBUG
-if(startpmapdebug)
-printf("pmap_remove: ptestart %x, pteslut %x, pv %x\n",ptestart, pteslut,pv);
+ RECURSESTART;
+ if (start & KERNBASE) { /* System space */
+ pt = Sysmap;
+#ifdef DIAGNOSTIC
+ if (((end & 0x3fffffff) >> VAX_PGSHIFT) > mfpr(PR_SLR))
+ panic("pmap_protect: outside SLR: %lx", end);
+#endif
+ start &= ~KERNBASE;
+ end &= ~KERNBASE;
+ pr = (prot & VM_PROT_WRITE ? PROT_KW : PROT_KR);
+ } else {
+ if (start & 0x40000000) { /* P1 space */
+ if (end <= pmap->pm_stack) {
+ RECURSEEND;
+ return;
+ }
+ if (start < pmap->pm_stack)
+ start = pmap->pm_stack;
+ pt = pmap->pm_p1br;
+#ifdef DIAGNOSTIC
+ if (((start & 0x3fffffff) >> VAX_PGSHIFT) < pmap->pm_p1lr)
+ panic("pmap_protect: outside P1LR");
+#endif
+ start &= 0x3fffffff;
+ end = (end == KERNBASE ? end >> 1 : end & 0x3fffffff);
+ } else { /* P0 space */
+ pt = pmap->pm_p0br;
+#ifdef DIAGNOSTIC
+ if ((end >> VAX_PGSHIFT) > (pmap->pm_p0lr & ~AST_MASK))
+ panic("pmap_protect: outside P0LR");
#endif
-
- s=splimp();
- for(countup=start;ptestart<pteslut;ptestart+=2, countup+=PAGE_SIZE){
-
- if(!(*ptestart&PG_FRAME))
- continue; /* not valid phys addr,no mapping */
-
- pv=PTE_TO_PV(*ptestart);
- if(!remove_pmap_from_mapping(pv,pmap)){
- panic("pmap_remove: pmap not in pv_table");
}
- *ptestart=0;
- *(ptestart+1)=0;
+ pr = (prot & VM_PROT_WRITE ? PROT_RW : PROT_RO);
}
- mtpr(0,PR_TBIA);
- splx(s);
-}
+ pts = &pt[start >> VAX_PGSHIFT];
+ ptd = &pt[end >> VAX_PGSHIFT];
+#ifdef DEBUG
+ if (((int)pts - (int)pt) & 7)
+ panic("pmap_remove: pts not even");
+ if (((int)ptd - (int)pt) & 7)
+ panic("pmap_remove: ptd not even");
+#endif
-int
-remove_pmap_from_mapping(pv, pmap)
- pv_entry_t pv;
- pmap_t pmap;
-{
- pv_entry_t temp_pv,temp2;
-
- if(!pv->pv_pmap&&pv->pv_next)
- panic("remove_pmap_from_mapping: j{ttefel");
-
- if(pv->pv_pmap==pmap){
- if(pv->pv_next){
- temp_pv=pv->pv_next;
- pv->pv_pmap=temp_pv->pv_pmap;
- pv->pv_va=temp_pv->pv_va;
- pv->pv_next=temp_pv->pv_next;
- free_pv_entry(temp_pv);
- } else {
- bzero(pv,sizeof(struct pv_entry));
- }
- } else {
- temp_pv=pv;
- while(temp_pv->pv_next){
- if(temp_pv->pv_next->pv_pmap==pmap){
- temp2=temp_pv->pv_next;
- temp_pv->pv_next=temp2->pv_next;
- free_pv_entry(temp2);
- return 1;
+ while (pts < ptd) {
+ if (kvtopte(pts)->pg_pfn && *(int *)pts) {
+ if (prot == VM_PROT_NONE) {
+ RECURSEEND;
+ if ((*(int *)pts & PG_SREF) == 0)
+ rensa(pts->pg_pfn >> LTOHPS, pts);
+ RECURSESTART;
+ bzero(pts, sizeof(struct pte) * LTOHPN);
+ pmap_decpteref(pmap, pts);
+ } else {
+ pts[0].pg_prot = pr;
+ pts[1].pg_prot = pr;
+ pts[2].pg_prot = pr;
+ pts[3].pg_prot = pr;
+ pts[4].pg_prot = pr;
+ pts[5].pg_prot = pr;
+ pts[6].pg_prot = pr;
+ pts[7].pg_prot = pr;
}
- temp_pv=temp_pv->pv_next;
}
- return 0;
+ pts += LTOHPN;
}
- return 1;
+ RECURSEEND;
+ mtpr(0,PR_TBIA);
}
-#ifndef notyet
-void
-pmap_copy_page(src, dst)
- vm_offset_t src;
- vm_offset_t dst;
+int pmap_simulref(int bits, int addr);
+/*
+ * Called from interrupt vector routines if we get a page invalid fault.
+ * Note: the save mask must be or'ed with 0x3f for this function.
+ * Returns 0 if normal call, 1 if CVAX bug detected.
+ */
+int
+pmap_simulref(int bits, int addr)
{
- int s;
- extern uint vmmap;
+ u_int *pte;
+ struct pv_entry *pv;
+ paddr_t pa;
#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_copy_page: src %x, dst %x\n",src, dst);
-#endif
- s=splimp();
- pte_cmap[0]=(src>>PGSHIFT)|PG_V|PG_RO;
- pte_cmap[1]=(dst>>PGSHIFT)|PG_V|PG_KW;
- mtpr(vmmap,PR_TBIS);
- mtpr(vmmap+NBPG,PR_TBIS);
- bcopy((void *)vmmap, (void *)vmmap+NBPG, NBPG);
- pte_cmap[0]=((src+NBPG)>>PGSHIFT)|PG_V|PG_RO;
- pte_cmap[1]=((dst+NBPG)>>PGSHIFT)|PG_V|PG_RW;
- mtpr(vmmap,PR_TBIS);
- mtpr(vmmap+NBPG,PR_TBIS);
- bcopy((void *)vmmap, (void *)vmmap+NBPG, NBPG);
- splx(s);
-}
-#else
- asm("
-
-_pmap_copy_page:.globl _pmap_copy_page
-
- .word 64
- mfpr $0x12, r6
- mtpr $0x16, $0x12 # splimp();
- movl _vmmap, r0
- movl _pte_cmap, r1
-
- ashl $-9, 4(ap), r2 # pte_cmap[0]=(src>>PGSHIFT)|PG_V|PG_RO;
- bisl3 $0xf8000000, r2, (r1)
- addl2 $4, r1
- addl3 $1, r2, (r1)+
-
- ashl $-9, 8(ap), r2 # pte_cmap[1]=(dst>>PGSHIFT)|PG_V|PG_KW;
- bisl3 $0xa0000000, r2, (r1)
- addl2 $4, r1
- addl3 $1, r2, (r1)
-
- mtpr $0, $57 # mtpr(0, PR_TBIA);
-
- addl3 $1024, r0, r1 # bcopy(vmmap, vmmap + 2 * NBPG, 2 * NBPG);
- movc3 $1024, (r0), (r1)
-
- mtpr r6, $0x12
- ret
-
- ");
-#endif
-
-pv_entry_t
-alloc_pv_entry()
-{
- pv_entry_t temporary;
-
- if(!pv_head) {
- temporary=(pv_entry_t)malloc(sizeof(struct pv_entry),
- M_VMPVENT, M_NOWAIT);
-#ifdef DIAGNOSTIC
- if (temporary == 0)
- panic("alloc_pv_entry");
+if (startpmapdebug)
+ printf("pmap_simulref: bits %x addr %x\n", bits, addr);
#endif
-#ifdef PMAPDEBUG
-if(startpmapdebug) printf("alloc_pv_entry: %x\n",temporary);
+#ifdef DEBUG
+ if (bits & 1)
+ panic("pte trans len");
#endif
+ /* Set addess on logical page boundary */
+ addr &= ~PGOFSET;
+ /* First decode userspace addr */
+ if (addr >= 0) {
+ if ((addr << 1) < 0)
+ pte = (u_int *)mfpr(PR_P1BR);
+ else
+ pte = (u_int *)mfpr(PR_P0BR);
+ pte += PG_PFNUM(addr);
+ if (bits & 2) { /* PTE reference */
+ pte = (u_int *)TRUNC_PAGE(pte);
+ pte = (u_int *)kvtopte(pte);
+ if (pte[0] == 0) /* Check for CVAX bug */
+ return 1;
+ pa = (u_int)pte & ~KERNBASE;
+ } else
+ pa = Sysmap[PG_PFNUM(pte)].pg_pfn << VAX_PGSHIFT;
} else {
- temporary=pv_head;
- pv_head=temporary->pv_next;
- pv_count--;
- }
- bzero(temporary, sizeof(struct pv_entry));
- return temporary;
-}
-
-void
-free_pv_entry(entry)
- pv_entry_t entry;
-{
- if(pv_count>=100) { /* Should be a define? */
- free(entry, M_VMPVENT);
- } else {
- entry->pv_next=pv_head;
- pv_head=entry;
- pv_count++;
+ pte = (u_int *)kvtopte(addr);
+ pa = (u_int)pte & ~KERNBASE;
}
+ pte[0] |= PG_V;
+ pte[1] |= PG_V;
+ pte[2] |= PG_V;
+ pte[3] |= PG_V;
+ pte[4] |= PG_V;
+ pte[5] |= PG_V;
+ pte[6] |= PG_V;
+ pte[7] |= PG_V;
+ pv = pv_table + (pa >> PGSHIFT);
+ pv->pv_attr |= PG_V; /* Referenced */
+ if (bits & 4)
+ pv->pv_attr |= PG_M; /* (will be) modified. XXX page tables */
+ return 0;
}
+/*
+ * Checks if page is referenced; returns true or false depending on result.
+ */
boolean_t
-pmap_is_referenced(pa)
- vm_offset_t pa;
+pmap_is_referenced(pg)
+ struct vm_page *pg;
{
- struct pv_entry *pv;
- u_int *pte,spte=0;
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ struct pv_entry *pv;
- pv=PHYS_TO_PV(pa);
+ pv = pv_table + (pa >> PGSHIFT);
+#ifdef PMAPDEBUG
+ if (startpmapdebug)
+ printf("pmap_is_referenced: pa %lx pv_entry %p ", pa, pv);
+#endif
- if(!pv->pv_pmap) return 0;
+ if (pv->pv_attr & PG_V)
+ return 1;
- do {
- pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
- spte|=*pte++;
- spte|=*pte;
- } while((pv=pv->pv_next));
- return((spte&PG_REF)?1:0);
+ return 0;
}
+/*
+ * Clears valid bit in all ptes referenced to this physical page.
+ */
boolean_t
-pmap_is_modified(pa)
- vm_offset_t pa;
+pmap_clear_reference(pg)
+ struct vm_page *pg;
{
- struct pv_entry *pv;
- u_int *pte, spte=0;
-
- pv=PHYS_TO_PV(pa);
- if(!pv->pv_pmap) return 0;
- do {
- pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
- spte|=*pte++;
- spte|=*pte;
- } while((pv=pv->pv_next));
- return((spte&PG_M)?1:0);
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ struct pv_entry *pv;
+
+ pv = pv_table + (pa >> PGSHIFT);
+#ifdef PMAPDEBUG
+ if (startpmapdebug)
+ printf("pmap_clear_reference: pa %lx pv_entry %p\n", pa, pv);
+#endif
+
+ pv->pv_attr &= ~PG_V;
+
+ RECURSESTART;
+ if (pv->pv_pte)
+ pv->pv_pte[0].pg_v = pv->pv_pte[1].pg_v =
+ pv->pv_pte[2].pg_v = pv->pv_pte[3].pg_v =
+ pv->pv_pte[4].pg_v = pv->pv_pte[5].pg_v =
+ pv->pv_pte[6].pg_v = pv->pv_pte[7].pg_v = 0;
+
+ while ((pv = pv->pv_next))
+ pv->pv_pte[0].pg_v = pv->pv_pte[1].pg_v =
+ pv->pv_pte[2].pg_v = pv->pv_pte[3].pg_v =
+ pv->pv_pte[4].pg_v = pv->pv_pte[5].pg_v =
+ pv->pv_pte[6].pg_v = pv->pv_pte[7].pg_v = 0;
+ RECURSEEND;
+ return TRUE; /* XXX */
}
/*
- * Reference bits are simulated and connected to logical pages,
- * not physical. This makes reference simulation much easier.
+ * Checks if page is modified; returns true or false depending on result.
*/
-
-void
-pmap_clear_reference(pa)
- vm_offset_t pa;
+boolean_t
+pmap_is_modified(pg)
+ struct vm_page *pg;
{
- struct pv_entry *pv;
- int *pte;
-/*
- * Simulate page reference bit
- */
- pv=PHYS_TO_PV(pa);
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ struct pv_entry *pv;
+
+ pv = pv_table + (pa >> PGSHIFT);
#ifdef PMAPDEBUG
-if(startpmapdebug) printf("pmap_clear_reference: pa %x, pv %x\n",pa,pv);
+ if (startpmapdebug)
+ printf("pmap_is_modified: pa %lx pv_entry %p ", pa, pv);
#endif
- pv->pv_flags&=~PV_REF;
- if(!pv->pv_pmap) return;
+ if (pv->pv_attr & PG_M) {
+#ifdef PMAPDEBUG
+ if (startpmapdebug)
+ printf("Yes: (0)\n");
+#endif
+ return 1;
+ }
- do {
- pte=(int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
- *pte&= ~(PG_REF|PG_V);
- *pte++|=PG_SREF;
- *pte&= ~(PG_REF|PG_V);
- *pte|=PG_SREF;
- } while((pv=pv->pv_next));
- mtpr(0,PR_TBIA);
-}
+ if (pv->pv_pte)
+ if ((pv->pv_pte[0].pg_m | pv->pv_pte[1].pg_m
+ | pv->pv_pte[2].pg_m | pv->pv_pte[3].pg_m
+ | pv->pv_pte[4].pg_m | pv->pv_pte[5].pg_m
+ | pv->pv_pte[6].pg_m | pv->pv_pte[7].pg_m)) {
+#ifdef PMAPDEBUG
+ if (startpmapdebug) printf("Yes: (1)\n");
+#endif
+ return 1;
+ }
-void
-pmap_clear_modify(pa)
- vm_offset_t pa;
-{
- struct pv_entry *pv;
- u_int *pte;
-
- pv=PHYS_TO_PV(pa);
- if(!pv->pv_pmap) return;
- do {
- pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
- *pte++&= ~PG_M;
- *pte&= ~PG_M;
- } while((pv=pv->pv_next));
+ while ((pv = pv->pv_next)) {
+ if ((pv->pv_pte[0].pg_m | pv->pv_pte[1].pg_m
+ | pv->pv_pte[2].pg_m | pv->pv_pte[3].pg_m
+ | pv->pv_pte[4].pg_m | pv->pv_pte[5].pg_m
+ | pv->pv_pte[6].pg_m | pv->pv_pte[7].pg_m)) {
+#ifdef PMAPDEBUG
+ if (startpmapdebug) printf("Yes: (2)\n");
+#endif
+ return 1;
+ }
+ }
+#ifdef PMAPDEBUG
+ if (startpmapdebug) printf("No\n");
+#endif
+ return 0;
}
-void
-pmap_change_wiring(pmap, va, wired)
- register pmap_t pmap;
- vm_offset_t va;
- boolean_t wired;
+/*
+ * Clears modify bit in all ptes referenced to this physical page.
+ */
+boolean_t
+pmap_clear_modify(pg)
+ struct vm_page *pg;
{
- int *pte;
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+ struct pv_entry *pv;
+
+ pv = pv_table + (pa >> PGSHIFT);
+
#ifdef PMAPDEBUG
-if(startpmapdebug) printf("pmap_change_wiring: pmap %x, va %x, wired %x\n",
- pmap, va, wired);
+ if (startpmapdebug)
+ printf("pmap_clear_modify: pa %lx pv_entry %p\n", pa, pv);
#endif
-
- pte=(int *)pmap_virt2pte(pmap,va);
- if(!pte) return; /* no pte allocated */
- if(wired) *pte|=PG_W;
- else *pte&=~PG_W;
+ pv->pv_attr &= ~PG_M;
+
+ if (pv->pv_pte)
+ pv->pv_pte[0].pg_m = pv->pv_pte[1].pg_m =
+ pv->pv_pte[2].pg_m = pv->pv_pte[3].pg_m =
+ pv->pv_pte[4].pg_m = pv->pv_pte[5].pg_m =
+ pv->pv_pte[6].pg_m = pv->pv_pte[7].pg_m = 0;
+
+ while ((pv = pv->pv_next))
+ pv->pv_pte[0].pg_m = pv->pv_pte[1].pg_m =
+ pv->pv_pte[2].pg_m = pv->pv_pte[3].pg_m =
+ pv->pv_pte[4].pg_m = pv->pv_pte[5].pg_m =
+ pv->pv_pte[6].pg_m = pv->pv_pte[7].pg_m = 0;
+ return TRUE; /* XXX */
}
/*
- * pmap_page_protect:
- *
- * Lower the permission for all mappings to a given page.
+ * Lower the permission for all mappings to a given page.
+ * Lower permission can only mean setting protection to either read-only
+ * or none; where none is unmapping of the page.
*/
void
-pmap_page_protect(pa, prot)
- vm_offset_t pa;
- vm_prot_t prot;
+pmap_page_protect(pg, prot)
+ struct vm_page *pg;
+ vm_prot_t prot;
{
- pv_entry_t pv,opv;
- u_int s,*pte,*pte1,nyprot,kprot;
-
+ struct pte *pt;
+ struct pv_entry *pv, *opv, *pl;
+ int s, *g;
+ paddr_t pa;
#ifdef PMAPDEBUG
-if(startpmapdebug) printf("pmap_page_protect: pa %x, prot %x\n",pa, prot);
+if(startpmapdebug) printf("pmap_page_protect: pg %p, prot %x, ",pg, prot);
+#endif
+ pa = VM_PAGE_TO_PHYS(pg);
+#ifdef PMAPDEBUG
+if(startpmapdebug) printf("pa %lx\n",pa);
#endif
- pv = PHYS_TO_PV(pa);
- if(!pv->pv_pmap) return;
- nyprot=prot_array[prot];
- kprot=kernel_prot[prot];
-
- switch (prot) {
- case VM_PROT_ALL:
- break;
- case VM_PROT_READ:
- case VM_PROT_READ|VM_PROT_EXECUTE:
- do {
- pte=pte1=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
- s=splimp();
- *pte1++&=~PG_PROT;
- *pte1&=~PG_PROT;
- if(pv->pv_va>0x7fffffff){
- *pte|=kprot;
- *pte1|=kprot;
- } else{
- *pte|=nyprot;
- *pte1|=nyprot;
- }
- splx(s);
- } while((pv=pv->pv_next));
- mtpr(0,PR_TBIA);
- break;
+ pv = pv_table + (pa >> PGSHIFT);
+ if (pv->pv_pte == 0 && pv->pv_next == 0)
+ return;
- default:
+ if (prot == VM_PROT_ALL) /* 'cannot happen' */
+ return;
- pte=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
+ RECURSESTART;
+ if (prot == VM_PROT_NONE) {
s = splimp();
- *pte++=0;
- *pte=0;
- opv=pv;
- pv=pv->pv_next;
- bzero(opv,sizeof(struct pv_entry));
- while(pv){
- pte=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
- *pte++=0;
- *pte=0;
- opv=pv;
- pv=pv->pv_next;
- free_pv_entry(opv);
+ g = (int *)pv->pv_pte;
+ if (g) {
+ if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
+ pv->pv_attr |=
+ g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
+ bzero(g, sizeof(struct pte) * LTOHPN);
+ pv->pv_pmap->pm_stats.resident_count--;
+ pmap_decpteref(pv->pv_pmap, pv->pv_pte);
+ pv->pv_pte = 0;
}
-
- mtpr(0,PR_TBIA);
+ pl = pv->pv_next;
+ pv->pv_pmap = 0;
+ pv->pv_next = 0;
+ while (pl) {
+ g = (int *)pl->pv_pte;
+ if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
+ pv->pv_attr |=
+ g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
+ bzero(g, sizeof(struct pte) * LTOHPN);
+ pl->pv_pmap->pm_stats.resident_count--;
+ pmap_decpteref(pl->pv_pmap, pl->pv_pte);
+ opv = pl;
+ pl = pl->pv_next;
+ free_pventry(opv);
+ }
splx(s);
- break;
+ } else { /* read-only */
+ do {
+ pt = pv->pv_pte;
+ if (pt == 0)
+ continue;
+ pt[0].pg_prot = pt[1].pg_prot =
+ pt[2].pg_prot = pt[3].pg_prot =
+ pt[4].pg_prot = pt[5].pg_prot =
+ pt[6].pg_prot = pt[7].pg_prot =
+ ((vaddr_t)pv->pv_pte < ptemapstart ?
+ PROT_KR : PROT_RO);
+ } while ((pv = pv->pv_next));
}
+ RECURSEEND;
+ mtpr(0, PR_TBIA);
}
/*
- * pmap_zero_page zeros the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bzero to clear its contents, one machine dependent page
- * at a time.
+ * Activate the address space for the specified process.
+ * Note that if the process to activate is the current process, then
+ * the processor internal registers must also be loaded; otherwise
+ * the current process will have wrong pagetables.
*/
void
-pmap_zero_page(phys)
- vm_offset_t phys;
+pmap_activate(p)
+ struct proc *p;
{
- int s;
+ pmap_t pmap;
+ struct pcb *pcb;
#ifdef PMAPDEBUG
-if(startpmapdebug)printf("pmap_zero_page(phys %x, vmmap %x, pte_cmap %x\n",
- phys,vmmap,pte_cmap);
+if(startpmapdebug) printf("pmap_activate: p %p\n", p);
#endif
- s = splimp();
- pte_cmap[0] = (phys >> PGSHIFT) | PG_V|PG_KW;
- pte_cmap[1] = pte_cmap[0] + 1;
- mtpr(vmmap, PR_TBIS);
- mtpr(vmmap+ NBPG, PR_TBIS);
- bzero((void *)vmmap, NBPG * 2);
- pte_cmap[0] = pte_cmap[1] = 0;
- mtpr(vmmap, PR_TBIS);
- mtpr(vmmap + NBPG, PR_TBIS);
- splx(s);
+
+ pmap = p->p_vmspace->vm_map.pmap;
+ pcb = &p->p_addr->u_pcb;
+
+ pcb->P0BR = pmap->pm_p0br;
+ pcb->P0LR = pmap->pm_p0lr;
+ pcb->P1BR = pmap->pm_p1br;
+ pcb->P1LR = pmap->pm_p1lr;
+
+ if (p == curproc) {
+ mtpr(pmap->pm_p0br, PR_P0BR);
+ mtpr(pmap->pm_p0lr, PR_P0LR);
+ mtpr(pmap->pm_p1br, PR_P1BR);
+ mtpr(pmap->pm_p1lr, PR_P1LR);
+ }
+ mtpr(0, PR_TBIA);
}
-pt_entry_t *
-pmap_virt2pte(pmap, vaddr)
- pmap_t pmap;
- u_int vaddr;
+struct pv_entry *pv_list;
+
+struct pv_entry *
+get_pventry()
{
- u_int *pte;
-
- if (vaddr < 0x40000000) {
- pte = (unsigned *)pmap->pm_pcb->P0BR;
- if ((vaddr >> PGSHIFT) > (pmap->pm_pcb->P0LR & ~AST_MASK))
- return 0;
- } else if (vaddr < (u_int)0x80000000) {
- pte = (unsigned *)pmap->pm_pcb->P1BR;
- if (((vaddr & 0x3fffffff) >> PGSHIFT) < pmap->pm_pcb->P1LR)
- return 0;
- } else
- pte = (u_int *)Sysmap;
-
- vaddr &= (u_int)0x3fffffff;
-
- return ((pt_entry_t *)&pte[vaddr >> PGSHIFT]);
+ struct pv_entry *tmp;
+ int s = splimp();
+
+ if (pventries == 0)
+ panic("get_pventry");
+
+ tmp = pv_list;
+ pv_list = tmp->pv_next;
+ pventries--;
+ splx(s);
+ return tmp;
}
void
-pmap_expandp0(pmap, ny_storlek)
- struct pmap *pmap;
+free_pventry(pv)
+ struct pv_entry *pv;
{
- u_int tmp, s, size, osize, oaddr, astlvl;
-
- astlvl = pmap->pm_pcb->P0LR & AST_MASK;
- osize = (pmap->pm_pcb->P0LR & ~AST_MASK) * 4;
- size = ny_storlek * 4;
- tmp = kmem_alloc_wait(pte_map, size);
- if (osize)
- blkcpy(pmap->pm_pcb->P0BR, (void*)tmp, osize);
+ int s = splimp();
- s = splimp();
- oaddr = (u_int)pmap->pm_pcb->P0BR;
- mtpr(tmp, PR_P0BR);
- mtpr(((size >> 2) | astlvl), PR_P0LR);
- mtpr(0, PR_TBIA);
- pmap->pm_pcb->P0BR = (void*)tmp;
- pmap->pm_pcb->P0LR = ((size >> 2) | astlvl);
+ pv->pv_next = pv_list;
+ pv_list = pv;
+ pventries++;
splx(s);
-
- if(osize)
- kmem_free_wakeup(pte_map, (vm_offset_t)oaddr, osize);
}
void
-pmap_expandp1(pmap)
- struct pmap *pmap;
+more_pventries()
{
- u_int tmp, s, size, osize, oaddr;
+ struct vm_page *pg;
+ struct pv_entry *pv;
+ vaddr_t v;
+ int s, i, count;
+
+ pg = uvm_pagealloc(NULL, 0, NULL, 0);
+ if (pg == 0)
+ return;
- osize = 0x800000 - (pmap->pm_pcb->P1LR * 4);
- size = osize + PAGE_SIZE;
- tmp = kmem_alloc_wait(pte_map, size);
+ v = VM_PAGE_TO_PHYS(pg) | KERNBASE;
+ pv = (struct pv_entry *)v;
+ count = NBPG/sizeof(struct pv_entry);
- if (osize)
- blkcpy((void*)pmap->pm_stack, (void*)tmp + PAGE_SIZE, osize);
+ for (i = 0; i < count; i++)
+ pv[i].pv_next = &pv[i + 1];
s = splimp();
- oaddr = pmap->pm_stack;
- pmap->pm_pcb->P1BR = (void*)(tmp + size - 0x800000);
- pmap->pm_pcb->P1LR = (0x800000 - size) >> 2;
- pmap->pm_stack = tmp;
- mtpr(pmap->pm_pcb->P1BR, PR_P1BR);
- mtpr(pmap->pm_pcb->P1LR, PR_P1LR);
- mtpr(0, PR_TBIA);
+ pv[count - 1].pv_next = pv_list;
+ pv_list = pv;
+ pventries += count;
splx(s);
-
- if (osize)
- kmem_free_wakeup(pte_map, (vm_offset_t)oaddr, osize);
}
-/* $OpenBSD: rootfil.c,v 1.7 1997/09/27 17:04:11 niklas Exp $ */
+/* $OpenBSD: rootfil.c,v 1.8 2000/04/27 01:10:13 bjc Exp $ */
/* $NetBSD: rootfil.c,v 1.14 1996/10/13 03:35:58 christos Exp $ */
/*
#include <machine/macros.h>
#include <machine/nexus.h>
#include <machine/sid.h>
+#include <machine/disklabel.h>
#include <machine/pte.h>
#include <machine/cpu.h>
#include "hp.h"
#include "ra.h"
+#include "sd.h"
#define DOSWAP /* Change swdevt, argdev, and dumpdev too */
#ifdef MAJA
void
setroot()
{
- int majdev, mindev, unit, part, controller, adaptor;
- dev_t temp = 0, orootdev;
- struct swdevt *swp;
+ int majdev, mindev, unit, part, controller, adaptor;
+ dev_t temp = 0, orootdev;
+ struct swdevt *swp;
extern int boothowto;
char *uname;
if (boothowto & RB_DFLTROOT ||
(bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
return;
- majdev = B_TYPE(bootdev);
- if (majdev >= nblkdev)
+ majdev = bdevtomaj(B_TYPE(bootdev));
+ if (majdev >= nblkdev || majdev == -1)
return;
adaptor = B_ADAPTOR(bootdev);
controller = B_CONTROLLER(bootdev);
return;
break;
+ case 20: /* SCSI disk */
+#if NSD
+ if((mindev = sd_getdev(adaptor, controller, part, unit, &uname)) < 0)
+#endif
+ return;
+ break;
+
default:
return;
}
- mindev = (mindev << PARTITIONSHIFT) + part;
orootdev = rootdev;
rootdev = makedev(majdev, mindev);
/*
-/* $OpenBSD: sbi.c,v 1.7 1997/05/29 00:05:24 niklas Exp $ */
-/* $NetBSD: sbi.c,v 1.14 1996/10/13 03:36:00 christos Exp $ */
+/* $OpenBSD: sbi.c,v 1.8 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: sbi.c,v 1.20 1999/08/07 10:36:50 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Still to do: Write all SBI error handling.
+ */
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/device.h>
#include <machine/nexus.h>
static int sbi_print __P((void *, const char *));
-static int sbi_match __P((struct device *, void *, void *));
+static int sbi_match __P((struct device *, struct cfdata *, void *));
static void sbi_attach __P((struct device *, struct device *, void*));
int
{
struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
int unsupp = 0;
- extern int nmba;
if (name) {
switch (sa->type) {
case NEX_MBA:
- printf("mba%d at %s",nmba++, name);
+ printf("mba at %s", name);
break;
default:
printf("unknown device 0x%x at %s", sa->type, name);
int
sbi_match(parent, cf, aux)
- struct device *parent;
- void *cf, *aux;
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
{
- struct bp_conf *bp = aux;
-
- if (strcmp(bp->type, "sbi"))
- return 0;
- return 1;
+ if (vax_bustype == VAX_SBIBUS)
+ return 1;
+ return 0;
}
void
struct device *parent, *self;
void *aux;
{
- u_int nexnum, maxnex, minnex;
+ u_int nexnum, minnex;
struct sbi_attach_args sa;
printf("\n");
- /*
- * Now a problem: on different machines with SBI units identifies
- * in different ways (if they identifies themselves at all).
- * We have to fake identifying depending on different CPUs.
- */
+#define NEXPAGES (sizeof(struct nexus) / VAX_NBPG)
minnex = self->dv_unit * NNEXSBI;
for (nexnum = minnex; nexnum < minnex + NNEXSBI; nexnum++) {
+ struct nexus *nexusP = 0;
volatile int tmp;
- if (badaddr((caddr_t)&nexus[nexnum], 4))
- continue;
-
- tmp = nexus[nexnum].nexcsr.nex_csr; /* no byte reads */
- sa.type = tmp & 255;
+ nexusP = (struct nexus *)vax_map_physmem((paddr_t)NEXA8600 +
+ sizeof(struct nexus) * nexnum, NEXPAGES);
+ if (badaddr((caddr_t)nexusP, 4)) {
+ vax_unmap_physmem((vaddr_t)nexusP, NEXPAGES);
+ } else {
+ tmp = nexusP->nexcsr.nex_csr; /* no byte reads */
+ sa.type = tmp & 255;
- sa.nexnum = nexnum;
- sa.nexaddr = nexus + nexnum;
- config_found(self, (void*)&sa, sbi_print);
+ sa.nexnum = nexnum;
+ sa.nexaddr = nexusP;
+ config_found(self, (void*)&sa, sbi_print);
+ }
}
}
-struct cfdriver sbi_cd = {
- NULL, "sbi", DV_DULL
+struct cfattach sbi_mainbus_ca = {
+ sizeof(struct device), sbi_match, sbi_attach
};
-struct cfattach sbi_ca = {
+struct cfattach sbi_abus_ca = {
sizeof(struct device), sbi_match, sbi_attach
};
-
--- /dev/null
+/* $OpenBSD: scb.c,v 1.1 2000/04/27 01:10:10 bjc Exp $ */
+/* $NetBSD: scb.c,v 1.9 2000/01/24 02:40:34 matt Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Routines for dynamic allocation/release of SCB vectors.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/trap.h>
+#include <machine/scb.h>
+#include <machine/frame.h>
+#include <machine/cpu.h>
+#include <machine/sid.h>
+#include <machine/mtpr.h>
+
+static void scb_stray __P((void *));
+
+static struct ivec_dsp *scb_vec;
+static volatile int vector, ipl, gotintr;
+extern int cold;
+/*
+ * Generates a new SCB.
+ */
+paddr_t
+scb_init(avail_start)
+ paddr_t avail_start;
+{
+ struct ivec_dsp **ivec = (struct ivec_dsp **)avail_start;
+ struct ivec_dsp **old = (struct ivec_dsp **)KERNBASE;
+ vaddr_t vavail = avail_start + KERNBASE;
+ int scb_size = dep_call->cpu_scbsz;
+ int i;
+
+ scb = (struct scb *)vavail;
+ scb_vec = (struct ivec_dsp *)(vavail + (scb_size * VAX_NBPG));
+
+ /* Init the whole SCB with interrupt catchers */
+ for (i = 0; i < (scb_size * VAX_NBPG)/4; i++) {
+ ivec[i] = &scb_vec[i];
+ (int)ivec[i] |= 1; /* On istack, please */
+ scb_vec[i] = idsptch;
+ scb_vec[i].hoppaddr = scb_stray;
+ scb_vec[i].pushlarg = (void *) (i * 4);
+ }
+ /*
+ * Copy all pre-set interrupt vectors to the new SCB.
+ * It is known that these vectors is at KERNBASE from the
+ * beginning, and that if the vector is zero it should call
+ * stray instead.
+ */
+ for (i = 0; i < 64; i++)
+ if (old[i])
+ ivec[i] = old[i];
+ /* Last action: set the SCB */
+ mtpr(avail_start, PR_SCBB);
+
+ /* Return new avail_start. Also save space for the dispatchers. */
+ return avail_start + (scb_size * 5) * VAX_NBPG;
+};
+
+/*
+ * Stray interrupt handler.
+ * This function must _not_ save any registers (in the reg save mask).
+ */
+void
+scb_stray(arg)
+ void *arg;
+{
+ struct callsframe *cf = FRAMEOFFSET(arg);
+ int *a = &cf->ca_arg1;
+
+ gotintr = 1;
+ vector = ((int) arg) & ~3;
+ ipl = mfpr(PR_IPL);
+ if (cold == 0)
+ printf("stray interrupt: vector 0x%x, ipl %d\n", vector, ipl);
+ else
+ a[8] = (a[8] & 0xffe0ffff) | ipl << 16;
+
+ mtpr(ipl + 1, PR_IPL);
+}
+
+/*
+ * Fake interrupt handler, to fool some bus' autodetect system.
+ * (May I say DW780? :-)
+ */
+void
+scb_fake(vec, br)
+ int vec, br;
+{
+ vector = vec;
+ ipl = br;
+ gotintr = 1;
+}
+
+/*
+ * Returns last vector/ipl referenced. Clears vector/ipl after reading.
+ */
+int
+scb_vecref(rvec, ripl)
+ int *rvec, *ripl;
+{
+ int save;
+
+ if (rvec)
+ *rvec = vector;
+ if (ripl)
+ *ripl = ipl;
+ save = gotintr;
+ gotintr = vector = ipl = 0;
+ mtpr(0, PR_IPL);
+ return save;
+}
+
+/*
+ * Sets a vector to the specified function.
+ * Arg may not be greater than 63.
+ */
+void
+scb_vecalloc(vecno, func, arg, stack)
+ int vecno;
+ void (*func) __P((void *));
+ void *arg;
+ int stack;
+{
+ struct ivec_dsp *dsp = &scb_vec[vecno / 4];
+ u_int *iscb = (u_int *)scb; /* XXX */
+ dsp->hoppaddr = func;
+ dsp->pushlarg = arg;
+ iscb[vecno/4] = (u_int)(dsp) | stack;
+}
--- /dev/null
+/* $OpenBSD: sgmap.c,v 1.1 2000/04/27 01:10:11 bjc Exp $ */
+/* $NetBSD: sgmap.c,v 1.3 1999/07/08 18:11:02 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/sgmap.h>
+
+void
+vax_sgmap_init(t, sgmap, name, sgvabase, sgvasize, ptva, minptalign)
+ bus_dma_tag_t t;
+ struct vax_sgmap *sgmap;
+ const char *name;
+ bus_addr_t sgvabase;
+ bus_size_t sgvasize;
+ struct pte *ptva;
+ bus_size_t minptalign;
+{
+ bus_dma_segment_t seg;
+ size_t ptsize;
+ int rseg;
+
+ if (sgvasize & PGOFSET) {
+ printf("size botch for sgmap `%s'\n", name);
+ goto die;
+ }
+
+ sgmap->aps_sgvabase = sgvabase;
+ sgmap->aps_sgvasize = sgvasize;
+
+ if (ptva != NULL) {
+ /*
+ * We already have a page table; this may be a system
+ * where the page table resides in bridge-resident SRAM.
+ */
+ sgmap->aps_pt = ptva;
+ } else {
+ /*
+ * Compute the page table size and allocate it. At minimum,
+ * this must be aligned to the page table size. However,
+ * some platforms have more strict alignment reqirements.
+ */
+ ptsize = (sgvasize / VAX_NBPG) * sizeof(struct pte);
+ if (minptalign != 0) {
+ if (minptalign < ptsize)
+ minptalign = ptsize;
+ } else
+ minptalign = ptsize;
+ if (bus_dmamem_alloc(t, ptsize, minptalign, 0, &seg, 1, &rseg,
+ BUS_DMA_NOWAIT)) {
+ panic("unable to allocate page table for sgmap `%s'\n",
+ name);
+ goto die;
+ }
+ sgmap->aps_pt = (struct pte *)(seg.ds_addr | KERNBASE);
+ }
+
+ /*
+ * Create the extent map used to manage the virtual address
+ * space.
+ */
+ sgmap->aps_ex = extent_create((char *)name, sgvabase, sgvasize - 1,
+ M_DEVBUF, NULL, 0, EX_NOWAIT|EX_NOCOALESCE);
+ if (sgmap->aps_ex == NULL) {
+ printf("unable to create extent map for sgmap `%s'\n", name);
+ goto die;
+ }
+
+ return;
+ die:
+ panic("vax_sgmap_init");
+}
+
+int
+vax_sgmap_alloc(map, origlen, sgmap, flags)
+ bus_dmamap_t map;
+ bus_size_t origlen;
+ struct vax_sgmap *sgmap;
+ int flags;
+{
+ int error;
+ bus_size_t len = origlen;
+
+#ifdef DIAGNOSTIC
+ if (map->_dm_flags & DMAMAP_HAS_SGMAP)
+ panic("vax_sgmap_alloc: already have sgva space");
+#endif
+
+ map->_dm_sgvalen = vax_round_page(len);
+
+#if 0
+ printf("len %x -> %x, _dm_sgvalen %x _dm_boundary %x boundary %x -> ",
+ origlen, len, map->_dm_sgvalen, map->_dm_boundary, boundary);
+#endif
+
+ error = extent_alloc(sgmap->aps_ex, map->_dm_sgvalen, VAX_NBPG,
+ 0, (flags & BUS_DMA_NOWAIT) ? EX_NOWAIT : EX_WAITOK,
+ &map->_dm_sgva);
+#if 0
+ printf("error %d _dm_sgva %x\n", error, map->_dm_sgva);
+#endif
+
+ if (error == 0)
+ map->_dm_flags |= DMAMAP_HAS_SGMAP;
+ else
+ map->_dm_flags &= ~DMAMAP_HAS_SGMAP;
+
+ return (error);
+}
+
+void
+vax_sgmap_free(map, sgmap)
+ bus_dmamap_t map;
+ struct vax_sgmap *sgmap;
+{
+
+#ifdef DIAGNOSTIC
+ if ((map->_dm_flags & DMAMAP_HAS_SGMAP) == 0)
+ panic("vax_sgmap_free: no sgva space to free");
+#endif
+
+ if (extent_free(sgmap->aps_ex, map->_dm_sgva, map->_dm_sgvalen,
+ EX_NOWAIT))
+ panic("vax_sgmap_free");
+
+ map->_dm_flags &= ~DMAMAP_HAS_SGMAP;
+}
+
+int
+vax_sgmap_load(t, map, buf, buflen, p, flags, sgmap)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ void *buf;
+ bus_size_t buflen;
+ struct proc *p;
+ int flags;
+ struct vax_sgmap *sgmap;
+{
+ vaddr_t endva, va = (vaddr_t)buf;
+ paddr_t pa;
+ bus_addr_t dmaoffset;
+ bus_size_t dmalen;
+ long *pte, *page_table = (long *)sgmap->aps_pt;
+ int pteidx, error;
+
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+ if (buflen > map->_dm_size)
+ return (EINVAL);
+
+ /*
+ * Remember the offset into the first page and the total
+ * transfer length.
+ */
+ dmaoffset = ((u_long)buf) & VAX_PGOFSET;
+ dmalen = buflen;
+
+
+ /*
+ * Allocate the necessary virtual address space for the
+ * mapping. Round the size, since we deal with whole pages.
+ *
+ * alpha_sgmap_alloc will deal with the appropriate spill page
+ * allocations.
+ *
+ */
+ endva = vax_round_page(va + buflen);
+ va = vax_trunc_page(va);
+ if ((map->_dm_flags & DMAMAP_HAS_SGMAP) == 0) {
+ error = vax_sgmap_alloc(map, (endva - va), sgmap, flags);
+ if (error)
+ return (error);
+ }
+
+ pteidx = map->_dm_sgva >> VAX_PGSHIFT;
+ pte = &page_table[pteidx];
+
+ /*
+ * Generate the DMA address.
+ */
+ map->dm_segs[0].ds_addr = map->_dm_sgva + dmaoffset;
+ map->dm_segs[0].ds_len = dmalen;
+
+
+ map->_dm_pteidx = pteidx;
+ map->_dm_ptecnt = 0;
+
+ /*
+ * Create the bus-specific page tables.
+ * Can be done much more efficient than this.
+ */
+ for (; va < endva; va += VAX_NBPG, pteidx++,
+ pte = &page_table[pteidx], map->_dm_ptecnt++) {
+ /*
+ * Get the physical address for this segment.
+ */
+ if (p != NULL)
+ pa = pmap_extract(p->p_vmspace->vm_map.pmap, va);
+ else
+ pa = kvtophys(va);
+
+ /*
+ * Load the current PTE with this page.
+ */
+ *pte = (pa >> VAX_PGSHIFT) | PG_V;
+ }
+
+ map->dm_mapsize = buflen;
+ map->dm_nsegs = 1;
+ return (0);
+}
+
+int
+vax_sgmap_load_mbuf(t, map, m, flags, sgmap)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct mbuf *m;
+ int flags;
+ struct vax_sgmap *sgmap;
+{
+
+ panic("vax_sgmap_load_mbuf : not implemented");
+}
+
+int
+vax_sgmap_load_uio(t, map, uio, flags, sgmap)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct uio *uio;
+ int flags;
+ struct vax_sgmap *sgmap;
+{
+
+ panic("vax_sgmap_load_uio : not implemented");
+}
+
+int
+vax_sgmap_load_raw(t, map, segs, nsegs, size, flags, sgmap)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ bus_size_t size;
+ int flags;
+ struct vax_sgmap *sgmap;
+{
+
+ panic("vax_sgmap_load_raw : not implemented");
+}
+
+void
+vax_sgmap_unload(t, map, sgmap)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct vax_sgmap *sgmap;
+{
+ long *pte, *page_table = (long *)sgmap->aps_pt;
+ int ptecnt, pteidx;
+
+ /*
+ * Invalidate the PTEs for the mapping.
+ */
+ for (ptecnt = map->_dm_ptecnt, pteidx = map->_dm_pteidx,
+ pte = &page_table[pteidx];
+ ptecnt != 0;
+ ptecnt--, pteidx++,
+ pte = &page_table[pteidx]) {
+ *pte = 0;
+ }
+
+ /*
+ * Free the virtual address space used by the mapping
+ * if necessary.
+ */
+ if ((map->_dm_flags & BUS_DMA_ALLOCNOW) == 0)
+ vax_sgmap_free(map, sgmap);
+ /*
+ * Mark the mapping invalid.
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+}
-/* $OpenBSD: subr.s,v 1.6 1997/09/10 12:04:52 maja Exp $ */
-/* $NetBSD: subr.s,v 1.18 1997/03/22 23:02:13 ragge Exp $ */
+/* $OpenBSD: subr.s,v 1.7 2000/04/27 01:10:13 bjc Exp $ */
+/* $NetBSD: subr.s,v 1.32 1999/03/25 00:41:48 mrg Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- /* All bugs are subject to removal without further notice */
-
-
-#include <sys/syscall.h>
-#include <sys/errno.h>
+#include <machine/asm.h>
-#include <machine/mtpr.h>
-#include <machine/vmparam.h>
-#include <machine/pte.h>
-#include <machine/nexus.h>
+#include "assym.h"
+#ifdef COMPAT_ULTRIX
+#include <compat/ultrix/ultrix_syscall.h>
+#endif
+#define JSBENTRY(x) .globl x ; .align 2 ; x :
.text
+/*
+ * First entry routine from boot. This should be in a file called locore.
+ */
+ASENTRY(start, 0)
+ movl r11,_boothowto # Howto boot (single etc...)
+ movl r10,_bootdev # From where? (see rpb.h)
+ bisl3 $0x80000000,r9,_esym # End of loaded code
+ movl r8,_avail_end # Usable memory (from VMB)
+ pushl $0x1f0000 # Push a nice PSL
+ pushl $to # Address to jump to
+ rei # change to kernel stack
+to: movw $0xfff,_panic # Save all regs in panic
+ addl3 _esym,$0x3ff,r0 # Round symbol table end
+ bicl3 $0x3ff,r0,_proc0paddr # save proc0 uarea pointer
+ bicl3 $0x80000000,_proc0paddr,r0 # get phys proc0 uarea addr
+ mtpr r0,$PR_PCBB # Save in IPR PCBB
+ addl3 $USPACE,_proc0paddr,r0 # Get kernel stack top
+ mtpr r0,$PR_KSP # put in IPR KSP
+ movl r0,_Sysmap # SPT start addr after KSP
+
+# Set some registers in known state
+ movl _proc0paddr,r0
+ clrl P0LR(r0)
+ clrl P1LR(r0)
+ mtpr $0,$PR_P0LR
+ mtpr $0,$PR_P1LR
+ movl $0x80000000,r1
+ movl r1,P0BR(r0)
+ movl r1,P1BR(r0)
+ mtpr r1,$PR_P0BR
+ mtpr r1,$PR_P1BR
+ clrl IFTRAP(r0)
+ mtpr $0,$PR_SCBB
+
+ calls $0,_start # Jump away.
+ /* NOTREACHED */
+
+
+/*
+ * Signal handler code.
+ */
+
.globl _sigcode,_esigcode
_sigcode: pushr $0x3f
subl2 $0xc,sp
calls $3,(r0)
popr $0x3f
chmk $SYS_sigreturn
+ chmk $SYS_exit
halt
.align 2
_esigcode:
+#ifdef COMPAT_ULTRIX
+ .globl _ultrix_sigcode,_ultrix_esigcode
+_ultrix_sigcode: pushr $0x3f
+ subl2 $0xc,sp
+ movl 0x24(sp),r0
+ calls $3,(r0)
+ popr $0x3f
+ chmk $ULTRIX_SYS_sigreturn
+ chmk $SYS_exit
+ halt
+ .align 2
+_ultrix_esigcode:
+#endif
+
.globl _idsptch, _eidsptch
_idsptch: pushr $0x3f
- pushl $1
- nop
- calls $1, *$0x12345678
- popr $0x3f
- rei
+ .word 0x9f16
+ .long _cmn_idsptch
+ .long 0
+ .long 0
_eidsptch:
- .globl _subyte
-_subyte: .word 0x0
- movl 4(ap),r0
-# probew $3,$1,(r0)
-# beql suerr
- movb 8(ap),(r0)
- clrl r0
- ret
-
-suerr: movl $-1,r0
- ret
-
- .globl _fubyte
-_fubyte: .word 0x0
- movl 4(ap),r0
-# prober $3,$1,(r0)
-# beql suerr
- movzbl (r0),r0
- ret
+_cmn_idsptch:
+ movl (sp)+,r0
+ pushl 4(r0)
+ calls $1,*(r0)
+ popr $0x3f
+ rei
-
- .globl _badaddr
-_badaddr: .word 0x0
- # Called with addr,b/w/l
+ENTRY(badaddr,0) # Called with addr,b/w/l
mfpr $0x12,r0
mtpr $0x1f,$0x12
- movl 4(ap),r2 # First argument, the address
- movl 8(ap),r1 # Sec arg, b,w,l
+ movl 4(ap),r2 # First argument, the address
+ movl 8(ap),r1 # Sec arg, b,w,l
pushl r0 # Save old IPL
clrl r3
- movl $4f,_memtest # Set the return adress
+ movab 4f,_memtest # Set the return address
caseb r1,$1,$4 # What is the size
1: .word 1f-1b
movl r3,r0
ret
-#
-# Speeded up locopyin/locopyout written by Ken Wellsch.
-#
-# locopyin (from, to, len, addr) copies from userspace to kernelspace.
-# addr is iftrap addr for faulting.
-#
- .globl _locopyin
- .align 2
-
-_locopyin: .word 0x3c # save R2|R3|R4|R5
-
- movl 4(ap),r4 # stash userspace address
- movl 12(ap),r3 # and length in case of fault?
-
- brb copyio
-
-#
-# locopyout (from, to, len, addr) copies from kernelspace to userspace.
-# addr is iftrap addr for faulting.
-#
- .globl _locopyout
- .align 2
-
-_locopyout: .word 0x3c # save R2|R3|R4|R5
-
- movl 8(ap),r4 # stash userspace address
- movl 12(ap),r3 # and length in case of fault?
-
-copyio:
-
- movl 12(ap),r2 # len
- beql 5f
-
- movl 16(ap),r0 # Get fault pointer flag
- movl $cio,(r0) # and stuff return address into it
-
- movl 4(ap),r0 # from
- movl 8(ap),r1 # to
-
- ashl $-3,r2,r5 # convert length to quad words
- beql 2f
-1:
- movq (r0)+,(r1)+ # do the copying in large hunks
- sobgtr r5,1b # (although movc3 is twice as fast
- # alas movc5 clobbers [r0-r5] thus
- # damaging the magic r3/r4 pair)
-2:
- bicl3 $-8,r2,r5 # compute trailing bytes (<=7)
- beql 4f
-3:
- movb (r0)+,(r1)+
- sobgtr r5,3b
-4:
- movl 16(ap),r0 # remove fault address
- clrl (r0)
-5:
- clrl r0 # flag the successful operation
-cio:
- ret
-
-
-#
-# copystr(from, to, maxlen, *copied, addr)
-# Only used in kernel mode, doesnt check accessability.
-#
-
- .globl _copystr
-_copystr: .word 0x7c
- movl 4(ap),r4 # from
- movl 8(ap),r5 # to
- movl 12(ap),r2 # len
- movl 16(ap),r3 # copied
-
-#if VAX630 || VAX650 || VAX410
- movl r4, r1 # (3) string address == r1
- movl r2, r0 # (2) string length == r0
- jeql Llocc_out # forget zero length strings
-Llocc_loop:
- tstb (r1)
- jeql Llocc_out
- incl r1
- sobgtr r0,Llocc_loop
-Llocc_out:
- tstl r0 # be sure of condition codes
-#else
- locc $0, r2, (r4) # check for null byte
-#endif
- beql 1f
-
- subl3 r0, r2, r6 # Len to copy.
- incl r6
- tstl r3
- beql 7f
- movl r6,(r3)
-7: movc3 r6,(r4),(r5)
- movl $0,r0
-cs: ret
-
-1: movc3 r2,(r4),(r5)
- movl $ENAMETOOLONG, r0
- ret
-
-
-_loswtch: .globl _loswtch
- mtpr _curpcb,$PR_PCBB
- svpctx
- mtpr _nypcb,$PR_PCBB
- ldpctx
- rei
-
- .data
-
-_memtest: .long 0 ; .globl _memtest # Memory test in progress.
-
# Have bcopy and bzero here to be sure that system files that not gets
# macros.h included will not complain.
-_bcopy: .globl _bcopy
- .word 0x0
+ENTRY(bcopy,0)
movl 4(ap), r0
movl 8(ap), r1
movl 0xc(ap), r2
movc3 r2, (r0), (r1)
ret
-_bzero: .globl _bzero
- .word 0x0
+ENTRY(bzero,0)
movl 4(ap), r0
movl 8(ap), r1
movc5 $0, (r0), $0, r1, (r0)
ret
+# cmpc3 is sometimes emulated; we cannot use it
+ENTRY(bcmp, 0);
+ movl 4(ap), r2
+ movl 8(ap), r1
+ movl 12(ap), r0
+2: cmpb (r2)+, (r1)+
+ bneq 1f
+ decl r0
+ bneq 2b
+1: ret
+
#ifdef DDB
/*
* DDB is the only routine that uses setjmp/longjmp.
_setjmp:.word 0
movl 4(ap), r0
movl 8(fp), (r0)
- movl 12(fp), 4(r0)
+ movl 12(fp), 4(r0)
movl 16(fp), 8(r0)
addl3 fp,$28,12(r0)
clrl r0
movl 12(r1), sp
jmp *8(r1)
#endif
+
+#
+# setrunqueue/remrunqueue fast variants.
+#
+
+JSBENTRY(Setrq)
+#ifdef DIAGNOSTIC
+ tstl 4(r0) # Check that process actually are off the queue
+ beql 1f
+ pushab setrq
+ calls $1,_panic
+setrq: .asciz "setrunqueue"
+#endif
+1: extzv $2,$6,P_PRIORITY(r0),r1 # get priority
+ movaq _qs[r1],r2 # get address of queue
+ insque (r0),*4(r2) # put proc last in queue
+ bbss r1,_whichqs,1f # set queue bit.
+1: rsb
+
+JSBENTRY(Remrq)
+ extzv $2,$6,P_PRIORITY(r0),r1
+#ifdef DIAGNOSTIC
+ bbs r1,_whichqs,1f
+ pushab remrq
+ calls $1,_panic
+remrq: .asciz "remrunqueue"
+#endif
+1: remque (r0),r2
+ bneq 1f # Not last process on queue
+ bbsc r1,_whichqs,1f
+1: clrl 4(r0) # saftey belt
+ rsb
+
+#
+# Idle loop. Here we could do something fun, maybe, like calculating
+# pi or something.
+#
+idle: mtpr $0,$PR_IPL # Enable all types of interrupts
+1: tstl _whichqs # Anything ready to run?
+ beql 1b # no, continue to loop
+ brb Swtch # Yes, goto switch again.
+
+#
+# cpu_switch, cpu_exit and the idle loop implemented in assembler
+# for efficiency. r0 contains pointer to last process.
+#
+
+JSBENTRY(Swtch)
+ clrl _curproc # Stop process accounting
+#bpt
+ mtpr $0x1f,$PR_IPL # block all interrupts
+ ffs $0,$32,_whichqs,r3 # Search for bit set
+ beql idle # no bit set, go to idle loop
+
+ movaq _qs[r3],r1 # get address of queue head
+ remque *(r1),r2 # remove proc pointed to by queue head
+#ifdef DIAGNOSTIC
+ bvc 1f # check if something on queue
+ pushab noque
+ calls $1,_panic
+noque: .asciz "swtch"
+#endif
+1: bneq 2f # more processes on queue?
+ bbsc r3,_whichqs,2f # no, clear bit in whichqs
+2: clrl 4(r2) # clear proc backpointer
+ clrl _want_resched # we are now changing process
+ movl r2,_curproc # set new process running
+ cmpl r0,r2 # Same process?
+ bneq 1f # No, continue
+ rsb
+xxd:
+1: movl P_ADDR(r2),r0 # Get pointer to new pcb.
+ addl3 r0,$IFTRAP,pcbtrap # Save for copy* functions.
+
+#
+# Nice routine to get physical from virtual adresses.
+#
+ extzv $9,$21,r0,r1 # extract offset
+ movl *_Sysmap[r1],r2 # get pte
+ ashl $9,r2,r3 # shift to get phys address.
+
+#
+# Do the actual process switch. pc + psl are already on stack, from
+# the calling routine.
+#
+ svpctx
+ mtpr r3,$PR_PCBB
+ ldpctx
+ rei
+
+#
+# the last routine called by a process.
+#
+
+ENTRY(cpu_exit,0)
+ movl 4(ap),r6 # Process pointer in r6
+ mtpr $0x18,$PR_IPL # Block almost everything
+ addl3 $512,_scratch,sp # Change stack, and schedule it to be freed
+
+ pushl P_VMSPACE(r6)
+ calls $1,_uvmspace_free
+
+ clrl r0 # No process to switch from
+ bicl3 $0xc0000000,_scratch,r1
+ mtpr r1,$PR_PCBB
+ brw Swtch
+
+
+#
+# copy/fetch/store routines.
+#
+
+ .globl _copyin, _copyout
+_copyout:
+_copyin:.word 0
+ movab 1f,*pcbtrap
+ movl 4(ap),r1
+ movl 8(ap),r2
+ movc3 12(ap),(r1), (r2)
+1: clrl *pcbtrap
+ ret
+
+ENTRY(kcopy,0)
+ movl *pcbtrap,-(sp)
+ movab 1f,*pcbtrap
+ movl 4(ap),r1
+ movl 8(ap),r2
+ movc3 12(ap),(r1), (r2)
+ clrl r1
+1: movl (sp)+,*pcbtrap
+ movl r1,r0
+ ret
+
+_copystr: .globl _copystr
+_copyinstr: .globl _copyinstr
+_copyoutstr: .globl _copyoutstr
+ .word 0
+ movl 4(ap),r4 # from
+ movl 8(ap),r5 # to
+ movl 12(ap),r2 # len
+ movl 16(ap),r3 # copied
+
+ movab 2f,*pcbtrap
+
+/*
+ * This routine consists of two parts: One is for MV2 that doesn't have
+ * locc in hardware, the other is a fast version with locc. But because
+ * locc only handles <64k strings, we default to the slow version if the
+ * string is longer.
+ */
+ cmpl _vax_cputype,$VAX_TYP_UV2
+ bneq 4f # Check if locc emulated
+
+9: movl r2,r0
+7: movb (r4)+,(r5)+
+ beql 6f
+ sobgtr r0,7b
+ brb 1f
+
+6: tstl r3
+ beql 5f
+ incl r2
+ subl3 r0,r2,(r3)
+5: clrl r0
+ clrl *pcbtrap
+ ret
+
+4: cmpl r2,$65535 # maxlen < 64k?
+ blss 8f # then use fast code.
+
+ locc $0,$65535,(r4) # is strlen < 64k?
+ beql 9b # No, use slow code
+ subl3 r0,$65535,r1 # Get string len
+ brb 0f # do the copy
+
+8: locc $0,r2,(r4) # check for null byte
+ beql 1f
+
+ subl3 r0,r2,r1 # Calculate len to copy
+0: incl r1 # Copy null byte also
+ tstl r3
+ beql 3f
+ movl r1,(r3) # save len copied
+3: movc3 r1,(r4),(r5)
+ brb 2f
+
+1: movl $ENAMETOOLONG,r0
+2: clrl *pcbtrap
+ ret
+
+ENTRY(subyte,0)
+ movab 1f,*pcbtrap
+ movl 4(ap),r0
+ movb 8(ap),(r0)
+ clrl r1
+1: clrl *pcbtrap
+ movl r1,r0
+ ret
+
+ENTRY(suword,0)
+ movab 1f,*pcbtrap
+ movl 4(ap),r0
+ movl 8(ap),(r0)
+ clrl r1
+1: clrl *pcbtrap
+ movl r1,r0
+ ret
+
+ENTRY(suswintr,0)
+ movab 1f,*pcbtrap
+ movl 4(ap),r0
+ movw 8(ap),(r0)
+ clrl r1
+1: clrl *pcbtrap
+ movl r1,r0
+ ret
+
+ENTRY(fuswintr,0)
+ movab 1f,*pcbtrap
+ movl 4(ap),r0
+ movzwl (r0),r1
+1: clrl *pcbtrap
+ movl r1,r0
+ ret
+
+#
+# data department
+#
+ .data
+
+_memtest: .long 0 ; .globl _memtest # Memory test in progress.
+pcbtrap: .long 0x800001fc; .globl pcbtrap # Safe place
+_bootdev: .long 0; .globl _bootdev
+
+/*
+ * Copy/zero more than 64k of memory (as opposite of bcopy/bzero).
+ */
+ENTRY(blkcpy,R6)
+ movl 4(ap),r1
+ movl 8(ap),r3
+ movl 12(ap),r6
+ jbr 2f
+1: subl2 r0,r6
+ movc3 r0,(r1),(r3)
+2: movzwl $65535,r0
+ cmpl r6,r0
+ jgtr 1b
+ movc3 r6,(r1),(r3)
+ ret
+
+ENTRY(blkclr,R6)
+ movl 4(ap), r3
+ movl 8(ap), r6
+ jbr 2f
+1: subl2 r0, r6
+ movc5 $0,(r3),$0,r0,(r3)
+2: movzwl $65535,r0
+ cmpl r6, r0
+ jgtr 1b
+ movc5 $0,(r3),$0,r6,(r3)
+ ret
-/* $OpenBSD: swapgeneric.c,v 1.6 1998/05/11 21:35:31 niklas Exp $ */
+/* $OpenBSD: swapgeneric.c,v 1.7 2000/04/27 01:10:13 bjc Exp $ */
/* $NetBSD: swapgeneric.c,v 1.13 1996/10/13 03:36:01 christos Exp $ */
/*-
long dumplo;
int dmmin, dmmax, dmtext;
-int (*mountroot) __P((void)) = dk_mountroot;
+int (*mountroot) __P((void)) = NULL;
extern struct cfdriver hp_cd;
extern struct cfdriver ra_cd;
-/* $OpenBSD: trap.c,v 1.11 1999/01/11 05:12:08 millert Exp $ */
-/* $NetBSD: trap.c,v 1.28 1997/07/28 21:48:33 ragge Exp $ */
-
+/* $OpenBSD: trap.c,v 1.12 2000/04/27 01:10:14 bjc Exp $ */
+/* $NetBSD: trap.c,v 1.47 1999/08/21 19:26:20 matt Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
*/
/* All bugs are subject to removal without further notice */
-
-
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <machine/pcb.h>
#include <machine/trap.h>
#include <machine/pmap.h>
+#include <machine/cpu.h>
#ifdef DDB
#include <machine/db_machdep.h>
#include <sys/ktrace.h>
#endif
-extern int want_resched,whichqs;
#ifdef TRAPDEBUG
-volatile int startsysc=0,faultdebug=0;
+volatile int startsysc = 0, faultdebug = 0;
#endif
-static void userret __P((struct proc *, u_int, u_int));
void arithflt __P((struct trapframe *));
void syscall __P((struct trapframe *));
-void showregs __P((struct trapframe *));
-void showstate __P((struct proc *));
-void stray __P((int, int));
-void printstack __P((u_int *, u_int *));
-
-void
-userret(p, pc, psl)
- struct proc *p;
- u_int pc, psl;
-{
- int s,sig;
-
- while ((sig = CURSIG(p)) !=0)
- postsig(sig);
- p->p_priority = p->p_usrpri;
- if (want_resched) {
- /*
- * Since we are curproc, clock will normally just change
- * our priority without moving us from one queue to another
- * (since the running process is not on a queue.)
- * If that happened after we setrunqueue ourselves but before
- * we swtch()'ed, we might not be on the queue indicated by
- * our priority.
- */
- s=splstatclock();
- setrunqueue(curproc);
- mi_switch();
- splx(s);
- while ((sig = CURSIG(curproc)) != 0)
- postsig(sig);
- }
-
- curpriority = curproc->p_priority;
-}
char *traptypes[]={
"reserved addressing",
};
int no_traps = 18;
+#define USERMODE(framep) ((((framep)->psl) & (PSL_U)) == PSL_U)
+#define FAULTCHK \
+ if (p->p_addr->u_pcb.iftrap) { \
+ frame->pc = (unsigned)p->p_addr->u_pcb.iftrap; \
+ frame->psl &= ~PSL_FPD; \
+ frame->r0 = EFAULT;/* for copyin/out */ \
+ frame->r1 = -1; /* for fetch/store */ \
+ return; \
+ }
+
void
arithflt(frame)
struct trapframe *frame;
{
- u_int sig, type = frame->trap, trapsig=1, s;
- u_int rv, addr;
+ u_int sig = 0, type = frame->trap, trapsig = 1;
+ u_int rv, addr, umode;
struct proc *p = curproc;
- struct pmap *pm;
+ u_quad_t oticks = 0;
vm_map_t map;
vm_prot_t ftype;
- extern vm_map_t pte_map;
- int typ;
- caddr_t v;
+ int typ;
union sigval sv;
-
- if ((frame->psl & PSL_U) == PSL_U) {
+
+ uvmexp.traps++;
+ if ((umode = USERMODE(frame))) {
type |= T_USER;
+ oticks = p->p_sticks;
p->p_addr->u_pcb.framep = frame;
}
- type &= ~(T_WRITE|T_PTEFETCH);
+ type&=~(T_WRITE|T_PTEFETCH);
#ifdef TRAPDEBUG
- if (frame->trap == 7)
- goto fram;
- if (faultdebug)
- printf("Trap: type %x, code %x, pc %x, psl %x\n",
- frame->trap, frame->code, frame->pc, frame->psl);
+if(frame->trap==7) goto fram;
+if(faultdebug)printf("Trap: type %lx, code %lx, pc %lx, psl %lx\n",
+ frame->trap, frame->code, frame->pc, frame->psl);
fram:
#endif
- switch (type) {
+ switch(type){
default:
-faulter:
#ifdef DDB
kdb_trap(frame);
#endif
printf("Trap: type %x, code %x, pc %x, psl %x\n",
- frame->trap, frame->code, frame->pc, frame->psl);
- showregs(frame);
- panic("trap: adr %x", frame->code);
+ (u_int)frame->trap, (u_int)frame->code,
+ (u_int)frame->pc, (u_int)frame->psl);
+ panic("trap");
+
case T_KSPNOTVAL:
- goto faulter;
+ panic("kernel stack invalid");
case T_TRANSFLT|T_USER:
- case T_TRANSFLT: /* Translation invalid - may be simul page ref */
- if (frame->trap & T_PTEFETCH) {
- u_int *ptep, *pte, *pte1;
-
- if (frame->code < 0x40000000)
- ptep = (u_int *)p->p_addr->u_pcb.P0BR;
- else
- ptep = (u_int *)p->p_addr->u_pcb.P1BR;
- pte1 = (u_int *)trunc_page(&ptep[(frame->code &
- 0x3fffffff) >> PGSHIFT]);
- pte = (u_int*)&Sysmap[((u_int)pte1 & 0x3fffffff) >>
- PGSHIFT];
- if (*pte & PG_SREF) { /* Yes, simulated */
- s = splhigh();
-
- *pte |= PG_REF|PG_V; *pte &= ~PG_SREF; pte++;
- *pte |= PG_REF|PG_V; *pte &= ~PG_SREF;
- mtpr(0, PR_TBIA);
- splx(s);
- goto uret;
- }
- } else {
- u_int *ptep, *pte;
-
- frame->code = trunc_page(frame->code);
- if (frame->code < 0x40000000) {
- ptep = (u_int *)p->p_addr->u_pcb.P0BR;
- pte = &ptep[(frame->code >> PGSHIFT)];
- } else if (frame->code > 0x7fffffff) {
- pte = (u_int *)&Sysmap[((u_int)frame->code &
- 0x3fffffff) >> PGSHIFT];
- } else {
- ptep = (u_int *)p->p_addr->u_pcb.P1BR;
- pte = &ptep[(frame->code & 0x3fffffff) >>
- PGSHIFT];
- }
- if (*pte & PG_SREF) {
- s = splhigh();
- *pte |= PG_REF|PG_V; *pte &= ~PG_SREF; pte++;
- *pte |= PG_REF|PG_V; *pte &= ~PG_SREF;
- /* mtpr(frame->code, PR_TBIS); */
- /* mtpr(frame->code + NBPG, PR_TBIS); */
- mtpr(0, PR_TBIA);
- splx(s);
- goto uret;
- }
+ case T_TRANSFLT:
+ /*
+ * BUG! BUG! BUG! BUG! BUG!
+ * Due to a hardware bug (at in least KA65x CPUs) a double
+ * page table fetch trap will cause a translation fault
+ * even if access in the SPT PTE entry specifies 'no access'.
+ * In for example section 6.4.2 in VAX Architecture
+ * Reference Manual it states that if a page both are invalid
+ * and have no access set, a 'access violation fault' occurs.
+ * Therefore, we must fall through here...
+ */
+#ifdef nohwbug
+ panic("translation fault");
+#endif
+ case T_ACCFLT|T_USER:
+ if (frame->code < 0) { /* Check for kernel space */
+ sig = SIGSEGV;
+ typ = SEGV_ACCERR;
+ break;
}
- /* Fall into... */
case T_ACCFLT:
- case T_ACCFLT|T_USER:
#ifdef TRAPDEBUG
- if (faultdebug)
- printf("trap accflt type %x, code %x, pc %x, psl %x\n",
- frame->trap, frame->code, frame->pc, frame->psl);
+if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
+ frame->trap, frame->code, frame->pc, frame->psl);
#endif
- if (!p)
- panic("trap: access fault without process");
- pm = &p->p_vmspace->vm_pmap;
- if (frame->trap&T_PTEFETCH) {
- u_int faultaddr;
- u_int testaddr = (u_int)frame->code & 0x3fffffff;
- int P0 = 0, P1 = 0, SYS = 0;
-
- if (frame->code == testaddr)
- P0++;
- else if (frame->code > 0x7fffffff)
- SYS++;
- else
- P1++;
-
- if (P0) {
- faultaddr = (u_int)pm->pm_pcb->P0BR +
- ((testaddr >> PGSHIFT) << 2);
- } else if (P1) {
- faultaddr = (u_int)pm->pm_pcb->P1BR +
- ((testaddr >> PGSHIFT) << 2);
- } else
- panic("pageflt: PTE fault in SPT");
-
- rv = vm_fault(pte_map, faultaddr & ~PAGE_MASK,
- VM_PROT_WRITE|VM_PROT_READ, FALSE);
- if (rv != KERN_SUCCESS) {
- typ = SEGV_MAPERR;
- v = (caddr_t)faultaddr;
- sig = SIGSEGV;
- goto bad;
- } else
- trapsig = 0;
- }
- addr = (frame->code & ~PAGE_MASK);
- if ((frame->pc >= (u_int)KERNBASE) &&
- (frame->code >= (u_int)KERNBASE)) {
+#ifdef DIAGNOSTIC
+ if (p == 0)
+ panic("trap: access fault: addr %lx code %lx",
+ frame->pc, frame->code);
+#endif
+
+ /*
+ * Page tables are allocated in pmap_enter(). We get
+ * info from below if it is a page table fault, but
+ * UVM may want to map in pages without faults, so
+ * because we must check for PTE pages anyway we don't
+ * bother doing it here.
+ */
+ addr = trunc_page(frame->code);
+ if ((umode == 0) && (frame->code < 0))
map = kernel_map;
- } else {
+ else
map = &p->p_vmspace->vm_map;
- }
+
if (frame->trap & T_WRITE)
ftype = VM_PROT_WRITE|VM_PROT_READ;
else
ftype = VM_PROT_READ;
- rv = vm_fault(map, addr, ftype, FALSE);
+ rv = uvm_fault(map, addr, 0, ftype);
if (rv != KERN_SUCCESS) {
- if (frame->pc >= (u_int)KERNBASE) {
- if (p->p_addr->u_pcb.iftrap) {
- frame->pc =
- (int)p->p_addr->u_pcb.iftrap;
- return;
- }
- printf("Segv in kernel mode: rv %d\n", rv);
- goto faulter;
+ if (umode == 0) {
+ FAULTCHK;
+ panic("Segv in kernel mode: pc %x addr %x",
+ (u_int)frame->pc, (u_int)frame->code);
+ }
+ if (rv == KERN_RESOURCE_SHORTAGE) {
+ printf("UVM: pid %d (%s), uid %d killed: "
+ "out of swap\n",
+ p->p_pid, p->p_comm,
+ p->p_cred && p->p_ucred ?
+ p->p_ucred->cr_uid : -1);
+ sig = SIGKILL;
+ typ = 0; /* XXX what goes here? (does it matter?) */
+ } else {
+ sig = SIGSEGV;
+ typ = SEGV_MAPERR;
}
- typ = SEGV_MAPERR;
- v = (caddr_t)frame->code;
- sig = SIGSEGV;
} else
- trapsig=0;
+ trapsig = 0;
break;
case T_PTELEN:
- case T_PTELEN|T_USER: /* Page table length exceeded */
- pm = &p->p_vmspace->vm_pmap;
-#ifdef TRAPDEBUG
- if (faultdebug)
- printf("trap ptelen type %x, code %x, pc %x, psl %x\n",
- frame->trap, frame->code, frame->pc, frame->psl);
-#endif
- if (frame->code < 0x40000000) { /* P0 */
- int i;
-
- if (p->p_vmspace == 0) {
- printf("no vmspace in fault\n");
- goto faulter;
- }
- i = p->p_vmspace->vm_tsize + p->p_vmspace->vm_dsize;
- if (i > (frame->code >> PAGE_SHIFT)) {
- pmap_expandp0(pm, i << 1);
- trapsig = 0;
- } else {
- typ = SEGV_MAPERR;
- v = (caddr_t)0xdeadbeef; /* XXX */
- sig = SIGSEGV;
- }
- } else if (frame->code > 0x7fffffff) { /* System, segv */
- typ = SEGV_MAPERR;
- v = (caddr_t)0xdeadbeef; /* XXX */
- sig = SIGSEGV;
- } else { /* P1 */
- int i;
+ if (p && p->p_addr)
+ FAULTCHK;
+ panic("ptelen fault in system space: addr %lx pc %lx",
+ frame->code, frame->pc);
- i = (u_int)(p->p_vmspace->vm_maxsaddr);
- if (frame->code < i) {
- typ = SEGV_MAPERR;
- v = (caddr_t)0xdeadbeef; /* XXX */
- sig = SIGSEGV;
- } else {
- pmap_expandp1(pm);
- trapsig = 0;
- }
- }
+ case T_PTELEN|T_USER: /* Page table length exceeded */
+ sig = SIGSEGV;
+ typ = SEGV_MAPERR;
break;
case T_BPTFLT|T_USER:
- case T_TRCTRAP|T_USER:
typ = TRAP_BRKPT;
- v = (caddr_t)0xdeadbeef; /* XXX */
+ sig = SIGTRAP;
+ frame->psl &= ~PSL_T;
+ break;
+
+ case T_TRCTRAP|T_USER:
+ typ = TRAP_TRACE;
sig = SIGTRAP;
frame->psl &= ~PSL_T;
break;
case T_PRIVINFLT|T_USER:
- case T_RESADFLT|T_USER:
case T_RESOPFLT|T_USER:
typ = ILL_ILLOPC;
- v = (caddr_t)0xdeadbeef; /* XXX */
+ sig = SIGILL;
+ break;
+
+ case T_RESADFLT|T_USER:
+ typ = ILL_ILLADR;
sig = SIGILL;
break;
case T_XFCFLT|T_USER:
- typ = 0; /* XXX/MAJA */
- v = (caddr_t)0; /* XXX/MAJA */
+ typ = ILL_ILLOPC; /* XXX hmm */
sig = SIGEMT;
break;
case T_ARITHFLT|T_USER:
- typ = FPE_FLTINV; /* XXX? */
- v = (caddr_t)0;
+ typ = 0; /* XXX */
sig = SIGFPE;
break;
case T_ASTFLT|T_USER:
- mtpr(AST_NO, PR_ASTLVL);
+ mtpr(AST_NO,PR_ASTLVL);
trapsig = 0;
break;
#ifdef DDB
+ case T_BPTFLT: /* Kernel breakpoint */
case T_KDBTRAP:
+ case T_KDBTRAP|T_USER:
+ case T_TRCTRAP:
kdb_trap(frame);
return;
#endif
}
-bad:
- if (trapsig) {
- sv.sival_ptr = v;
- trapsignal(curproc, sig, frame->code, typ, sv);
+
+ if (trapsig) {
+ sv.sival_ptr = (caddr_t)frame->pc;
+ trapsignal(p, sig, frame->code, typ, sv);
}
-uret:
- userret(curproc, frame->pc, frame->psl);
-};
-void
-showstate(p)
- struct proc *p;
-{
-if(p){
- printf("\npid %d, command %s\n",p->p_pid, p->p_comm);
- printf("text size %x, data size %x, stack size %x\n",
- p->p_vmspace->vm_tsize, p->p_vmspace->vm_dsize,p->p_vmspace->
- vm_ssize);
- printf("virt text %x, virt data %x, max stack %x\n",
- (u_int)p->p_vmspace->vm_taddr, (u_int)p->p_vmspace->vm_daddr,
- (u_int)p->p_vmspace->vm_maxsaddr);
- printf("kernel uarea %x, end uarea %x\n",(u_int)p->p_addr,
- (u_int)p->p_addr + USPACE);
-} else {
- printf("No process\n");
-}
- printf("kernel stack: %x, interrupt stack %x\n",
- mfpr(PR_KSP),mfpr(PR_ISP));
- printf("P0BR %x, P0LR %x, P1BR %x, P1LR %x\n",
- mfpr(PR_P0BR),mfpr(PR_P0LR),mfpr(PR_P1BR),mfpr(PR_P1LR));
+ if (umode == 0)
+ return;
+
+ while ((sig = CURSIG(p)) !=0)
+ postsig(sig);
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happened after we setrunqueue ourselves but before
+ * we swtch()'ed, we might not be on the queue indicated by
+ * our priority.
+ */
+ splstatclock();
+ setrunqueue(p);
+ mi_switch();
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+ if (p->p_flag & P_PROFIL) {
+ extern int psratio;
+ addupc_task(p, frame->pc, (int)(p->p_sticks-oticks) * psratio);
+ }
+ curpriority = p->p_priority;
}
void
setregs(p, pack, stack, retval)
- struct proc *p;
+ struct proc *p;
struct exec_package *pack;
- u_long stack;
- register_t retval[2];
+ u_long stack;
+ register_t *retval;
{
struct trapframe *exptr;
exptr = p->p_addr->u_pcb.framep;
exptr->pc = pack->ep_entry + 2;
exptr->sp = stack;
- retval[0] = retval[1] = 0;
+ exptr->r6 = stack; /* for ELF */
+ exptr->r7 = 0; /* for ELF */
+ exptr->r8 = 0; /* for ELF */
+ exptr->r9 = (u_long) PS_STRINGS; /* for ELF */
+
+ retval[1] = 0;
}
void
struct trapframe *frame;
{
struct sysent *callp;
- int nsys;
+ u_quad_t oticks;
+ int nsys, sig;
int err, rval[2], args[8];
struct trapframe *exptr;
struct proc *p = curproc;
#ifdef TRAPDEBUG
-if(startsysc)printf("trap syscall %s pc %x, psl %x, sp %x, pid %d, frame %x\n",
- syscallnames[frame->code], frame->pc, frame->psl,frame->sp,
+if(startsysc)printf("trap syscall %s pc %lx, psl %lx, sp %lx, pid %d, frame %p\n",
+ syscallnames[frame->code], frame->pc, frame->psl,frame->sp,
curproc->p_pid,frame);
#endif
-
+ uvmexp.syscalls++;
+
exptr = p->p_addr->u_pcb.framep = frame;
callp = p->p_emul->e_sysent;
nsys = p->p_emul->e_nsysent;
+ oticks = p->p_sticks;
if(frame->code == SYS___syscall){
int g = *(int *)(frame->ap);
- frame->code=*(int *)(frame->ap+4);
- frame->ap+=8;
- *(int *)(frame->ap)=g-2;
+ frame->code = *(int *)(frame->ap + 4);
+ frame->ap += 8;
+ *(int *)(frame->ap) = g - 2;
}
- if(frame->code<0||frame->code>=nsys)
+ if(frame->code < 0 || frame->code >= nsys)
callp += p->p_emul->e_nosys;
else
callp += frame->code;
- rval[0]=0;
- rval[1]=frame->r1;
+ rval[0] = 0;
+ rval[1] = frame->r1;
if(callp->sy_narg) {
- err = copyin((char*)frame->ap+4, args, callp->sy_argsize);
+ err = copyin((char*)frame->ap + 4, args, callp->sy_argsize);
if (err) {
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
goto bad;
}
}
+ /*
+ * XXX ***TAKE THIS OUT SOON***
+ * this is an evil hack to get around incongruities in (some) syscall
+ * argument types
+ */
+ switch(frame->code) {
+ case SYS_open:
+ args[2] &= 0xffff;
+ break;
+
+ case SYS_mkdir:
+ case SYS_chmod:
+ case SYS_fchmod:
+ case SYS_mkfifo:
+ case SYS_mknod:
+ args[1] &= 0xffff;
+ break;
+
+ case SYS_umask:
+ args[0] &= 0xffff;
+ }
+
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
ktrsyscall(p->p_tracep, frame->code, callp->sy_argsize, args);
#endif
- err=(*callp->sy_call)(curproc,args,rval);
+ err = (*callp->sy_call)(curproc, args, rval);
exptr = curproc->p_addr->u_pcb.framep;
#ifdef TRAPDEBUG
if(startsysc)
- printf("retur %s pc %x, psl %x, sp %x, pid %d, v{rde %d r0 %d, r1 %d, frame %x\n",
- syscallnames[exptr->code], exptr->pc, exptr->psl,exptr->sp,
- curproc->p_pid,err,rval[0],rval[1],exptr);
+ printf("retur %s pc %lx, psl %lx, sp %lx, pid %d, v{rde %d r0 %d, r1 %d, frame %p\n",
+ syscallnames[exptr->code], exptr->pc, exptr->psl,exptr->sp,
+ curproc->p_pid,err,rval[0],rval[1],exptr);
#endif
bad:
return;
case ERESTART:
- exptr->pc = exptr->pc-2;
+ exptr->pc -= (exptr->code > 63 ? 4 : 2);
break;
default:
exptr->psl |= PSL_C;
break;
}
- userret(curproc, exptr->pc, exptr->psl);
+ p = curproc;
+ while ((sig = CURSIG(p)) !=0)
+ postsig(sig);
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happened after we setrunqueue ourselves but before
+ * we swtch()'ed, we might not be on the queue indicated by
+ * our priority.
+ */
+ splstatclock();
+ setrunqueue(p);
+ mi_switch();
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+ if (p->p_flag & P_PROFIL) {
+ extern int psratio;
+ addupc_task(p, frame->pc, (int)(p->p_sticks-oticks) * psratio);
+ }
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, frame->code, err, rval[0]);
#endif
}
-
-void
-stray(scb, vec)
- int scb, vec;
-{
- printf("stray interrupt scb %d, vec 0x%x\n", scb, vec);
-}
-
-void
-printstack(loaddr, highaddr)
- u_int *loaddr, *highaddr;
-{
- u_int *tmp;
-
- (u_int)tmp = 0xfffffffc & (u_int)loaddr; /* Easy align */
-
- for (;tmp < highaddr;tmp += 4)
- printf("%8x: %8x %8x %8x %8x\n",
- (int)tmp, *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3));
-}
-
-void
-showregs(frame)
- struct trapframe *frame;
-{
- printf("P0BR %8x P1BR %8x P0LR %8x P1LR %8x\n",
- mfpr(PR_P0BR), mfpr(PR_P1BR), mfpr(PR_P0LR), mfpr(PR_P1LR));
- printf("KSP %8x ISP %8x USP %8x\n",
- mfpr(PR_KSP), mfpr(PR_ISP), mfpr(PR_USP));
- printf("R0 %8x R1 %8x R2 %8x R3 %8x\n",
- frame->r0, frame->r1, frame->r2, frame->r3);
- printf("R4 %8x R5 %8x R6 %8x R7 %8x\n",
- frame->r4, frame->r5, frame->r6, frame->r7);
- printf("R8 %8x R9 %8x R10 %8x R11 %8x\n",
- frame->r8, frame->r9, frame->r10, frame->r11);
- printf("FP %8x AP %8x PC %8x PSL %8x\n",
- frame->fp, frame->ap, frame->pc, frame->psl);
-}
-/* $OpenBSD: vm_machdep.c,v 1.15 1999/08/17 10:32:18 niklas Exp $ */
-/* $NetBSD: vm_machdep.c,v 1.33 1997/07/06 22:38:22 ragge Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.16 2000/04/27 01:10:14 bjc Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.56 2000/01/20 22:19:00 sommerfeld Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- /* All bugs are subject to removal without further notice */
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
fpte = kvtopte(from);
tpte = kvtopte(to);
- stor = (size >> PGSHIFT) * sizeof(struct pte);
+ stor = (size >> VAX_PGSHIFT) * sizeof(struct pte);
bcopy(fpte, tpte, stor);
bzero(fpte, stor);
mtpr(0, PR_TBIA);
}
-#define VIRT2PHYS(x) \
- (((*(int *)((((((int)x) & 0x7fffffff) >> 9) * 4) + \
- (unsigned int)Sysmap)) & 0x1fffff) << 9)
-
/*
+ * Finish a fork operation, with process p2 nearly set up.
+ * Copy and update the pcb and trap frame, making the child ready to run.
+ *
+ * Rig the child's kernel stack so that it will start out in
+ * proc_trampoline() and call child_return() with p2 as an
+ * argument. This causes the newly-created child process to go
+ * directly to user level with an apparent return value of 0 from
+ * fork(), while the parent process returns normally.
+ *
+ * p1 is the process being forked; if p1 == &proc0, we are creating
+ * a kernel thread, and the return path will later be changed in cpu_set_kpc.
+ *
+ * If an alternate user-level stack is requested (with non-zero values
+ * in both the stack and stacksize args), set up the user stack pointer
+ * accordingly.
+ *
* cpu_fork() copies parent process trapframe directly into child PCB
* so that when we swtch() to the child process it will go directly
* back to user mode without any need to jump back through kernel.
void *stack;
size_t stacksize;
{
+ struct pte *pt;
struct pcb *nyproc;
struct trapframe *tf;
struct pmap *pmap, *opmap;
+#ifdef DIAGNOSTIC
+ /*
+ * if p1 != curproc && p1 == &proc0, we're creating a kernel thread.
+ */
+ if (p1 != curproc && p1 != &proc0)
+ panic("cpu_fork: curproc");
+#endif
+
nyproc = &p2->p_addr->u_pcb;
tf = p1->p_addr->u_pcb.framep;
- opmap = &p1->p_vmspace->vm_pmap;
- pmap = &p2->p_vmspace->vm_pmap;
- pmap->pm_pcb = nyproc;
+ opmap = p1->p_vmspace->vm_map.pmap;
+ pmap = p2->p_vmspace->vm_map.pmap;
-#ifdef notyet
/* Mark page invalid */
- p2pte = kvtopte((u_int *)p2->p_addr + 2 * NBPG);
- *p2pte = 0;
-#endif
+ pt = kvtopte((u_int)p2->p_addr + REDZONEADDR);
+ pt->pg_v = 0;
-#ifdef notyet
- /* Set up internal defs in PCB, and alloc PTEs. */
- nyproc->P0BR = kmem_alloc_wait(pte_map,
- (opmap->pm_pcb->P0LR & ~AST_MASK) * 4);
- nyproc->P1BR = kmem_alloc_wait(pte_map,
- (0x800000 - (pmap->pm_pcb->P1LR * 4))) - 0x800000;
- nyproc->P0LR = opmap->pm_pcb->P0LR;
- nyproc->P1LR = opmap->pm_pcb->P1LR;
-#else
- nyproc->P0BR = (void *)0x80000000;
- nyproc->P1BR = (void *)0x80000000;
- nyproc->P0LR = AST_PCB;
- nyproc->P1LR = 0x200000;
-#endif
+ /*
+ * Activate address space for the new process. The PTEs have
+ * already been allocated by way of pmap_create().
+ */
+ pmap_activate(p2);
+
+ /* Set up internal defs in PCB. */
nyproc->iftrap = NULL;
nyproc->KSP = (u_int)p2->p_addr + USPACE;
nyproc->R[1] = 1;
return; /* Child is ready. Parent, return! */
-
}
/*
kc->cf.ca_pc = (unsigned)&sret;
kc->cf.ca_argno = 1;
kc->cf.ca_arg1 = (unsigned)arg;
- kc->tf.r11 = boothowto; /* If we have old init */
+ kc->tf.r11 = boothowto; /* If we have old init */
kc->tf.psl = 0x3c00000;
nyproc->framep = (void *)&kc->tf;
nyproc->PC = (unsigned)pc + 2;
}
-/*
- * Put in a process on the correct run queue based on it's priority
- * and set the bit corresponding to the run queue.
- */
-void
-setrunqueue(p)
- struct proc *p;
-{
- struct prochd *q;
- int knummer;
-
- if (p->p_back)
- panic("sket sig i setrunqueue");
-
- knummer = (p->p_priority >> 2);
- bitset(knummer, whichqs);
- q = &qs[knummer];
-
- _insque(p, q);
-
- return;
-}
-
-/*
- * Remove a process from the run queue. If this is the last process
- * on that queue, clear the queue bit in whichqs.
- */
-void
-remrunqueue(p)
- struct proc *p;
-{
- struct proc *qp;
- int bitnr;
-
- bitnr = (p->p_priority >> 2);
- if (bitisclear(bitnr, whichqs))
- panic("remrunqueue: Process not in queue");
-
- _remque(p);
-
- qp = (struct proc *)&qs[bitnr];
- if (qp->p_forw == qp)
- bitclear(bitnr, whichqs);
-}
-
-volatile caddr_t curpcb, nypcb;
-
-/*
- * Machine dependent part of switch function. Find the next process
- * with the highest priority to run. If the process queues are empty,
- * sleep waiting for something to happen. The idle loop resides here.
- */
-void
-cpu_switch(pp)
- struct proc *pp;
-{
- int i,s;
- struct proc *p, *q;
- extern unsigned int scratch;
-
-again:
- /* First: Search for a queue. */
- s = splhigh();
- if ((i = ffs(whichqs) - 1) < 0)
- goto idle;
-
- /*
- * A queue with runnable processes found.
- * Get first process from queue.
- */
- asm(".data;savpsl: .long 0;.text;movpsl savpsl");
- q = (struct proc *)&qs[i];
- if (q->p_forw == q)
- panic("swtch: no process queued");
-
- /* Remove process from queue */
- bitclear(i, whichqs);
- p = q->p_forw;
- _remque(p);
-
- if (q->p_forw != q)
- bitset(i, whichqs);
- if (curproc)
- (u_int)curpcb = VIRT2PHYS(&curproc->p_addr->u_pcb);
- else
- (u_int)curpcb = scratch & 0x7fffffff;
- (u_int)nypcb = VIRT2PHYS(&p->p_addr->u_pcb);
-
- if (p == 0)
- panic("switch: null proc pointer");
- want_resched = 0;
- curproc = p;
-
- /* Don't change process if it's the same that we'r already running */
- if (curpcb == nypcb)
- return;
-
- asm("pushl savpsl");
- asm("jsb _loswtch");
-
- return; /* New process! */
-
-idle:
- p = curproc;
- curproc = NULL; /* This is nice. /BQT */
- spl0();
- while (whichqs == 0)
- ;
- curproc = p;
- goto again;
-}
-
-/* Should check that values is in bounds XXX */
-int
-copyinstr(from, to, maxlen, lencopied)
- const void *from;
- void *to;
- size_t *lencopied;
- size_t maxlen;
-{
- u_int i;
- void *addr=&curproc->p_addr->u_pcb.iftrap;
- const char *gfrom = from;
- char *gto = to;
-
- asm("movl $Lstr,(%0)":: "r"(addr));
- for(i=0;i<maxlen;i++){
- *(gto +i )=*(gfrom + i);
- if(!(*(gto+i))) goto ok;
- }
-
- return(ENAMETOOLONG);
-ok:
- if(lencopied) *lencopied=i+1;
- return(0);
-}
-
-asm("Lstr: ret");
-
-/* Should check that values is in bounds XXX */
-int
-copyoutstr(from, to, maxlen, lencopied)
- const void *from;
- void *to;
- size_t *lencopied;
- size_t maxlen;
-{
- u_int i;
- const char *gfrom=from;
- char *gto=to;
- void *addr=&curproc->p_addr->u_pcb.iftrap;
-
- asm("movl $Lstr,(%0)":: "r"(addr));
- for(i=0;i<maxlen;i++){
- *(gto+i)=*(gfrom+i);
- if(!(*(gto+i))) goto ok;
- }
-
- return(ENAMETOOLONG);
-ok:
- if(lencopied) *lencopied=i+1;
- return 0;
-}
-
-int reno_zmagic __P((struct proc *, struct exec_package *));
-
-
int
cpu_exec_aout_makecmds(p, epp)
struct proc *p;
struct exec_package *epp;
{
- int error;
- struct exec *ep;
- /*
- * Compatibility with reno programs.
- */
- ep=epp->ep_hdr;
- switch (ep->a_midmag) {
- case 0x10b: /* ZMAGIC in 4.3BSD Reno programs */
- error = reno_zmagic(p, epp);
- break;
- case 0x108:
-printf("Warning: reno_nmagic\n");
- error = exec_aout_prep_nmagic(p, epp);
- break;
- case 0x107:
-printf("Warning: reno_omagic\n");
- error = exec_aout_prep_omagic(p, epp);
- break;
- default:
- error = ENOEXEC;
- }
- return(error);
+ return ENOEXEC;
}
int
return (ENOSYS);
};
-#ifdef COMPAT_ULTRIX
-extern struct emul emul_ultrix;
-#endif
-/*
- * 4.3BSD Reno programs have an 1K header first in the executable
- * file, containing a.out header. Otherwise programs are identical.
- *
- * from: exec_aout.c,v 1.9 1994/01/28 23:46:59 jtc Exp $
- */
-
-int
-reno_zmagic(p, epp)
- struct proc *p;
- struct exec_package *epp;
-{
- struct exec *execp = epp->ep_hdr;
-
- epp->ep_taddr = 0;
- epp->ep_tsize = execp->a_text;
- epp->ep_daddr = epp->ep_taddr + execp->a_text;
- epp->ep_dsize = execp->a_data + execp->a_bss;
- epp->ep_entry = execp->a_entry;
-
-#ifdef COMPAT_ULTRIX
- epp->ep_emul = &emul_ultrix;
-#endif
-
- /*
- * check if vnode is in open for writing, because we want to
- * demand-page out of it. if it is, don't do it, for various
- * reasons
- */
- if ((execp->a_text != 0 || execp->a_data != 0) &&
- epp->ep_vp->v_writecount != 0) {
- return ETXTBSY;
- }
- epp->ep_vp->v_flag |= VTEXT;
-
- /* set up command for text segment */
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text,
- epp->ep_taddr, epp->ep_vp, 0x400, VM_PROT_READ|VM_PROT_EXECUTE);
-
- /* set up command for data segment */
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data,
- epp->ep_daddr, epp->ep_vp, execp->a_text+0x400,
- VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
-
- /* set up command for bss segment */
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss,
- epp->ep_daddr + execp->a_data, NULLVP, 0,
- VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
-
- return exec_setup_stack(p, epp);
-}
-
-void
-cpu_exit(p)
- struct proc *p;
-{
- extern unsigned int scratch;
-
- if (p == 0)
- panic("cpu_exit from null process");
- vmspace_free(p->p_vmspace);
-
- (void) splimp();
- /* Must change kernel stack before freeing */
- mtpr(scratch + NBPG, PR_KSP);
- kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES));
- cpu_switch(0);
- /* NOTREACHED */
-}
-
-int
-suword(ptr, val)
- void *ptr;
- long val;
-{
- void *addr=&curproc->p_addr->u_pcb.iftrap;
-
- asm("movl $Lstr,(%0)":: "r"(addr));
- *(int *)ptr=val;
- return 0;
-}
-
/*
* Dump the machine specific header information at the start of a core dump.
* First put all regs in PCB for debugging purposes. This is not an good
int error;
tf = p->p_addr->u_pcb.framep;
- CORE_SETMAGIC(*chdr, COREMAGIC, MID_VAX, 0);
+ CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
chdr->c_hdrsize = sizeof(struct core);
chdr->c_seghdrsize = sizeof(struct coreseg);
chdr->c_cpusize = sizeof(struct md_coredump);
bcopy(tf, &state, sizeof(struct md_coredump));
- CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_VAX, CORE_CPU);
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
cseg.c_addr = 0;
cseg.c_size = chdr->c_cpusize;
if (error)
return error;
- error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&state, sizeof(state),
- (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
- IO_NODELOCKED|IO_UNIT, cred, NULL, p);
-
- if (!error)
- chdr->c_nseg++;
-
- return error;
-}
-
-int locopyout __P((const void *, void *, size_t, void *));
-int locopyin __P((const void *, void *, size_t, void *));
-
-int
-copyout(from, to, len)
- const void *from;
- void *to;
- size_t len;
-{
- void *addr=&curproc->p_addr->u_pcb.iftrap;
-
- return locopyout(from, to, len, addr);
-}
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&state, sizeof(state),
+ (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
-int
-copyin(from, to, len)
- const void *from;
- void *to;
- size_t len;
-{
- void *addr = &curproc->p_addr->u_pcb.iftrap;
+ if (!error)
+ chdr->c_nseg++;
- return locopyin(from, to, len, addr);
+ return error;
}
/*
- * cpu_swapin() is called just before a process shall be swapped in.
- * Kernel stack and pcb must be mapped when we swtch() to this new
- * process, to guarantee that we frob all pages here to ensure that
- * they actually are in-core. Kernel stack red zone is also updated
- * here.
+ * Kernel stack red zone need to be set when a process is swapped in.
*/
void
cpu_swapin(p)
struct proc *p;
{
- u_int uarea, i, *j, rv;
-
- uarea = (u_int)p->p_addr;
-
- for (i = uarea;i < uarea + USPACE;i += PAGE_SIZE) {
- j = (u_int *)kvtopte(i);
- if ((*j & PG_V) == 0) {
- rv = vm_fault(kernel_map, i,
- VM_PROT_WRITE|VM_PROT_READ, FALSE);
- if (rv != KERN_SUCCESS)
- panic("cpu_swapin: rv %d",rv);
- }
- }
-#ifdef notyet
- j = (u_int *)kvtopte(uarea + 2 * NBPG);
- *j = 0; /* Set kernel stack red zone */
-#endif
+ kvtopte((vaddr_t)p->p_addr + REDZONEADDR)->pg_v = 0;
}
-#if VAX410 || VAX43
/*
- * vmapbuf()/vunmapbuf() only used on some vaxstations without
- * any busadapter with MMU.
- * XXX - This must be reworked to be effective.
+ * Map in a bunch of pages read/writeable for the kernel.
*/
void
-vmapbuf(bp, len)
- struct buf *bp;
- vm_size_t len;
+ioaccess(vaddr, paddr, npgs)
+ vaddr_t vaddr;
+ paddr_t paddr;
+ int npgs;
{
- vm_offset_t faddr, taddr, off, pa;
- pmap_t fmap, tmap;
-
- if ((vax_boardtype != VAX_BTYP_43) && (vax_boardtype != VAX_BTYP_410))
- return;
- faddr = trunc_page(bp->b_saveaddr = bp->b_data);
- off = (vm_offset_t)bp->b_data - faddr;
- len = round_page(off + len);
- taddr = kmem_alloc_wait(phys_map, len);
- bp->b_data = (caddr_t)(taddr + off);
- fmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
- tmap = vm_map_pmap(phys_map);
- len = len >> PGSHIFT;
- while (len--) {
- volatile int i = *(int *)faddr;
-
- pa = pmap_extract(fmap, faddr);
- if (pa == 0)
- panic("vmapbuf: null page frame for %x", faddr);
-
- pmap_enter(tmap, taddr, pa & ~(NBPG - 1),
- VM_PROT_READ|VM_PROT_WRITE, TRUE);
- faddr += NBPG;
- taddr += NBPG;
- }
+ u_int *pte = (u_int *)kvtopte(vaddr);
+ int i;
+
+ for (i = 0; i < npgs; i++)
+ pte[i] = PG_V | PG_KW | (PG_PFNUM(paddr) + i);
}
/*
- * Free the io map PTEs associated with this IO operation.
- * We also invalidate the TLB entries and restore the original b_addr.
+ * Opposite to the above: just forget their mapping.
*/
void
-vunmapbuf(bp, len)
- struct buf *bp;
- vm_size_t len;
+iounaccess(vaddr, npgs)
+ vaddr_t vaddr;
+ int npgs;
{
- vm_offset_t addr, off;
-
- if ((vax_boardtype != VAX_BTYP_43) && (vax_boardtype != VAX_BTYP_410))
- return;
- addr = trunc_page(bp->b_data);
- off = (vm_offset_t)bp->b_data - addr;
- len = round_page(off + len);
- kmem_free_wakeup(phys_map, addr, len);
- bp->b_data = bp->b_saveaddr;
- bp->b_saveaddr = 0;
+ u_int *pte = (u_int *)kvtopte(vaddr);
+ int i;
+
+ for (i = 0; i < npgs; i++)
+ pte[i] = 0;
+ mtpr(0, PR_TBIA);
}
-#endif