From: bjc Date: Thu, 27 Apr 2000 01:10:09 +0000 (+0000) Subject: sync with netbsd of early april; some archs still untested X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=961264fdfebf8d31b6b4cab2acaa7d8d77e2bd10;p=openbsd sync with netbsd of early april; some archs still untested --- diff --git a/sys/arch/vax/vax/autoconf.c b/sys/arch/vax/vax/autoconf.c index ad349c2e281..38c99ddbf63 100644 --- a/sys/arch/vax/vax/autoconf.c +++ b/sys/arch/vax/vax/autoconf.c @@ -1,5 +1,5 @@ -/* $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. @@ -50,333 +50,108 @@ #include #include #include +#include + +#include "sd.h" +#include "cd.h" #include +#include + +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 -}; diff --git a/sys/arch/vax/vax/bus_dma.c b/sys/arch/vax/vax/bus_dma.c new file mode 100644 index 00000000000..ec111ba3d22 --- /dev/null +++ b/sys/arch/vax/vax/bus_dma.c @@ -0,0 +1,777 @@ +/* $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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define _VAX_BUS_DMA_PRIVATE +#include + +#include +#include + +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, +}; diff --git a/sys/arch/vax/vax/bus_mem.c b/sys/arch/vax/vax/bus_mem.c new file mode 100644 index 00000000000..3374b600ab7 --- /dev/null +++ b/sys/arch/vax/vax/bus_mem.c @@ -0,0 +1,132 @@ +/* $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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +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 +}; diff --git a/sys/arch/vax/vax/cfl.c b/sys/arch/vax/vax/cfl.c index b7345dd5883..3818797ad9a 100644 --- a/sys/arch/vax/vax/cfl.c +++ b/sys/arch/vax/vax/cfl.c @@ -1,5 +1,5 @@ -/* $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. @@ -200,6 +200,8 @@ cflstart() #endif } +void cfltint __P((int)); + void cfltint(arg) int arg; @@ -214,7 +216,7 @@ cfltint(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; @@ -232,6 +234,8 @@ cfltint(arg) } } +void cflrint __P((int)); + void cflrint(ch) int ch; diff --git a/sys/arch/vax/vax/clock.c b/sys/arch/vax/vax/clock.c index 20e382a6055..1b55c2335e6 100644 --- a/sys/arch/vax/vax/clock.c +++ b/sys/arch/vax/vax/clock.c @@ -1,5 +1,5 @@ -/* $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. @@ -42,9 +42,10 @@ #include #include #include +#include -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. @@ -55,19 +56,26 @@ void 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++; @@ -80,13 +88,6 @@ microtime(tvp) 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); } @@ -118,11 +119,11 @@ inittodr(fs_time) 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; } @@ -153,29 +154,17 @@ delay(i) 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 @@ -253,7 +242,7 @@ generic_clkwrite() } #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 */ @@ -285,7 +274,7 @@ chip_clkread(base) } 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); @@ -312,7 +301,7 @@ chip_clkwrite() 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); diff --git a/sys/arch/vax/vax/cmi.c b/sys/arch/vax/vax/cmi.c new file mode 100644 index 00000000000..21dc53f3070 --- /dev/null +++ b/sys/arch/vax/vax/cmi.c @@ -0,0 +1,131 @@ +/* $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 +#include +#include + +#include +#include +#include +#include + +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); +} diff --git a/sys/arch/vax/vax/conf.c b/sys/arch/vax/vax/conf.c index b4158343e35..8e575209296 100644 --- a/sys/arch/vax/vax/conf.c +++ b/sys/arch/vax/vax/conf.c @@ -1,5 +1,5 @@ -/* $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. @@ -44,6 +44,8 @@ #include #include +#include + #include "hp.h" /* 0 */ bdev_decl(hp); @@ -76,6 +78,7 @@ bdev_decl(ctu); #include "ra.h" bdev_decl(ra); +bdev_decl(rx); #include "up.h" bdev_decl(up); @@ -86,9 +89,6 @@ bdev_decl(ut); #include "rb.h" bdev_decl(idc); -#include "rx.h" -bdev_decl(rx); - #include "uu.h" bdev_decl(uu); @@ -98,11 +98,15 @@ bdev_decl(rl); #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); @@ -113,6 +117,15 @@ bdev_decl(st); #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? */ @@ -127,52 +140,108 @@ struct bdevsw bdevsw[] = 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 -#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 } }; @@ -180,7 +249,7 @@ struct consdev constab[]={ /* 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, \ @@ -211,6 +280,11 @@ struct consdev constab[]={ (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); @@ -240,11 +314,12 @@ cdev_decl(ut); 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); @@ -267,7 +342,7 @@ cdev_decl(np); #define crlwrite crlrw cdev_decl(crl); -#if VAX8200 && 0 +#if VAX8200 #define NCRX 1 #else #define NCRX 0 @@ -276,7 +351,6 @@ cdev_decl(crl); #define crxwrite crxrw cdev_decl(crx); -#ifdef notyet #if VAX780 #define NCFL 1 #else @@ -285,7 +359,6 @@ cdev_decl(crx); #define cflread cflrw #define cflwrite cflrw cdev_decl(cfl); -#endif #include "dz.h" cdev_decl(dz); @@ -320,18 +393,9 @@ cdev_decl(dhu); #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); @@ -362,10 +426,11 @@ cdev_decl(uk); 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 */ @@ -376,11 +441,7 @@ struct cdevsw cdevsw[] = 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 */ @@ -402,19 +463,19 @@ struct cdevsw cdevsw[] = 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 */ @@ -422,11 +483,7 @@ struct cdevsw cdevsw[] = 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 */ @@ -434,16 +491,26 @@ struct cdevsw cdevsw[] = 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]); @@ -524,12 +591,26 @@ int chrtoblktbl[] = { 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); @@ -539,6 +620,24 @@ chrtoblk(dev) 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. */ @@ -546,7 +645,6 @@ int iskmemdev(dev) dev_t dev; { - return (major(dev) == 3 && minor(dev) < 2); } @@ -562,20 +660,3 @@ iszerodev(dev) 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); -} diff --git a/sys/arch/vax/vax/crl.c b/sys/arch/vax/vax/crl.c index ba6eb4c8d08..efb49a37655 100644 --- a/sys/arch/vax/vax/crl.c +++ b/sys/arch/vax/vax/crl.c @@ -1,5 +1,5 @@ -/* $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. @@ -67,7 +67,7 @@ struct { int crl_ds; /* saved drive status */ } crlstat; -void crlintr __P((int)); +void crlintr __P((void *)); void crlattach __P((void)); static void crlstart __P((void)); @@ -81,11 +81,9 @@ struct ivec_dsp crl_intr; 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*/ @@ -192,13 +190,13 @@ crlstart() 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; diff --git a/sys/arch/vax/vax/crl.h b/sys/arch/vax/vax/crl.h index 81d8c61190a..7a2c1a8e4e3 100644 --- a/sys/arch/vax/vax/crl.h +++ b/sys/arch/vax/vax/crl.h @@ -1,5 +1,5 @@ -/* $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 */ @@ -22,8 +22,8 @@ * * * 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. * ****************************************************************/ diff --git a/sys/arch/vax/vax/crx.c b/sys/arch/vax/vax/crx.c new file mode 100644 index 00000000000..96b937389e9 --- /dev/null +++ b/sys/arch/vax/vax/crx.c @@ -0,0 +1,266 @@ +/* $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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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); +} diff --git a/sys/arch/vax/vax/crx.h b/sys/arch/vax/vax/crx.h new file mode 100644 index 00000000000..8dc0fc383e9 --- /dev/null +++ b/sys/arch/vax/vax/crx.h @@ -0,0 +1,86 @@ +/* $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) */ diff --git a/sys/arch/vax/vax/ctu.c b/sys/arch/vax/vax/ctu.c index d435ae86a7e..25089a2d7e3 100644 --- a/sys/arch/vax/vax/ctu.c +++ b/sys/arch/vax/vax/ctu.c @@ -1,5 +1,5 @@ -/* $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. @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -69,7 +70,7 @@ enum tu_state { 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 */ @@ -81,13 +82,13 @@ volatile struct tu_softc { 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 *)); @@ -99,18 +100,20 @@ void ctustrategy __P((struct buf *)); 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 @@ -131,7 +134,7 @@ ctuopen(dev, oflags, devtype, p) 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; @@ -161,7 +164,7 @@ ctuclose(dev, oflags, devtype, p) mtpr(0, PR_CSRS); mtpr(0, PR_CSTS); tu_sc.sc_state = SC_UNUSED; - untimeout(ctuwatch, 0); + callout_stop(&ctu_watch_ch); return 0; } @@ -178,12 +181,12 @@ ctustrategy(bp) #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); @@ -214,7 +217,7 @@ ctustart(bp) tu_sc.sc_state = SC_SEND_CMD; if (tu_sc.sc_xmtok) { tu_sc.sc_xmtok = 0; - ctutintr(0); + ctutintr(NULL); } } @@ -244,12 +247,12 @@ ctudump(dev, blkno, va, size) 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: @@ -269,12 +272,12 @@ cturintr(arg) #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; } @@ -294,12 +297,12 @@ cturintr(arg) 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: @@ -316,7 +319,7 @@ cturintr(arg) void ctutintr(arg) - int arg; + void *arg; { int c; @@ -398,12 +401,12 @@ ctuwatch(arg) 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) diff --git a/sys/arch/vax/vax/db_disasm.c b/sys/arch/vax/vax/db_disasm.c index 6a2c7b1fb12..e5180f183c3 100644 --- a/sys/arch/vax/vax/db_disasm.c +++ b/sys/arch/vax/vax/db_disasm.c @@ -1,5 +1,5 @@ -/* $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. @@ -38,10 +38,13 @@ #include #include #include +#include #include #include #include +#include +#include #include @@ -481,7 +484,7 @@ add_str(ib, s) inst_buffer *ib; char *s; { - while (*ib->curp++ = *s++); + while ((*ib->curp++ = *s++)); *--ib->curp = '\0'; } diff --git a/sys/arch/vax/vax/db_machdep.c b/sys/arch/vax/vax/db_machdep.c index 4cd85342ac6..7b1b6e170cd 100644 --- a/sys/arch/vax/vax/db_machdep.c +++ b/sys/arch/vax/vax/db_machdep.c @@ -1,5 +1,5 @@ -/* $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 @@ -12,7 +12,7 @@ * 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. * @@ -27,6 +27,9 @@ * 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 :-) + * */ /* @@ -35,14 +38,18 @@ */ #include #include +#include #include #include /* just for boothowto --eichin */ #include +#include + #include #include #include +#include #include #include @@ -60,6 +67,28 @@ void kdbprinttrap __P((int, int)); 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 - D on keyboard, via a TRACE or * BPT trap or from kernel, normally as a result of a panic. @@ -77,6 +106,7 @@ kdb_trap(frame) 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; @@ -88,8 +118,9 @@ kdb_trap(frame) 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; @@ -109,14 +140,12 @@ kdb_trap(frame) /* 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) @@ -150,15 +179,10 @@ kdbprinttrap(type, code) 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); } /* @@ -167,23 +191,18 @@ db_read_bytes(addr, size, data) 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); } /* @@ -210,14 +229,273 @@ struct db_variable db_regs[] = { }; 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; @@ -246,3 +524,4 @@ kdbrint(tkn) ddbescape = 0; return 0; } + diff --git a/sys/arch/vax/vax/disksubr.c b/sys/arch/vax/vax/disksubr.c index 9b82f3cf8b1..50c24538d8e 100644 --- a/sys/arch/vax/vax/disksubr.c +++ b/sys/arch/vax/vax/disksubr.c @@ -1,5 +1,5 @@ -/* $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. @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -50,10 +51,9 @@ #include #include #include +#include -#include /* For disk encoding scheme */ - -#define b_cylin b_resid +#include /* For disk encoding scheme */ /* * Determine the size of the transfer, and make sure it is @@ -67,11 +67,10 @@ bounds_check_with_label(bp, lp, osdep, wlabel) 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) { @@ -80,34 +79,30 @@ bounds_check_with_label(bp, lp, osdep, wlabel) } /* 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: @@ -151,27 +146,19 @@ readdisklabel(dev, strat, lp, osdep, spoofonly) 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; @@ -179,6 +166,13 @@ readdisklabel(dev, strat, lp, osdep, spoofonly) return (msg); } +void +dk_establish(p, q) + struct disk *p; + struct device *q; +{ +} + /* * Check new disk label for sensibility * before setting it. @@ -189,7 +183,7 @@ setdisklabel(olp, nlp, openmask, osdep) 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 || @@ -263,10 +257,10 @@ void 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)); } @@ -281,15 +275,17 @@ disk_reallymapin(bp, map, reg, flag) 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. @@ -297,8 +293,10 @@ disk_reallymapin(bp, map, reg, flag) */ 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); } @@ -310,9 +308,9 @@ disk_reallymapin(bp, map, reg, flag) 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); } diff --git a/sys/arch/vax/vax/findcpu.c b/sys/arch/vax/vax/findcpu.c new file mode 100644 index 00000000000..35f8825ac8c --- /dev/null +++ b/sys/arch/vax/vax/findcpu.c @@ -0,0 +1,132 @@ +/* $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 +#include + +#include +#include +#include +#include + +/* + * 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"); + } +} diff --git a/sys/arch/vax/vax/genassym.cf b/sys/arch/vax/vax/genassym.cf new file mode 100644 index 00000000000..38c3413d4a3 --- /dev/null +++ b/sys/arch/vax/vax/genassym.cf @@ -0,0 +1,117 @@ +# $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 +include +include +include + +include + +include +include +include +include +include + +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 diff --git a/sys/arch/vax/vax/gencons.c b/sys/arch/vax/vax/gencons.c index 9ae23f7d4e5..2453e5355c1 100644 --- a/sys/arch/vax/vax/gencons.c +++ b/sys/arch/vax/vax/gencons.c @@ -1,5 +1,5 @@ -/* $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 @@ -51,26 +51,30 @@ #include #include #include +#include #include -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) @@ -82,19 +86,18 @@ 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; @@ -106,8 +109,10 @@ gencnopen(dev, flag, mode, p) } 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)); } @@ -118,8 +123,10 @@ gencnclose(dev, flag, mode, p) 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); @@ -129,7 +136,7 @@ struct tty * gencntty(dev) dev_t dev; { - return gencn_tty[0]; /* XXX */ + return gencn_tty[minor(dev)]; } int @@ -138,7 +145,7 @@ gencnread(dev, 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_read)(tp, uio, flag)); } @@ -149,7 +156,8 @@ gencnwrite(dev, 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)); } @@ -161,14 +169,15 @@ gencnioctl(dev, cmd, data, flag, p) 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; } @@ -188,7 +197,7 @@ gencnstart(tp) 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; @@ -201,29 +210,32 @@ out: splx(s); } 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; @@ -231,11 +243,11 @@ gencnstop(tp, 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); @@ -257,10 +269,9 @@ void 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; @@ -272,6 +283,23 @@ void 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 @@ -300,3 +328,17 @@ gencngetc(dev) 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); + } +} diff --git a/sys/arch/vax/vax/gencons.h b/sys/arch/vax/vax/gencons.h index 31be13218a3..b33b435b9f0 100644 --- a/sys/arch/vax/vax/gencons.h +++ b/sys/arch/vax/vax/gencons.h @@ -1,5 +1,5 @@ -/* $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. @@ -33,7 +33,6 @@ */ /* All bugs are subject to removal without further notice */ - /* * Some definitions for generic console interface (PR 32-35) @@ -42,10 +41,8 @@ /* 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 */ @@ -56,8 +53,20 @@ #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)); diff --git a/sys/arch/vax/vax/ibus.c b/sys/arch/vax/vax/ibus.c new file mode 100644 index 00000000000..cd752d37842 --- /dev/null +++ b/sys/arch/vax/vax/ibus.c @@ -0,0 +1,124 @@ +/* $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 +#include +#include + +#include +#include +#include + +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); + +} diff --git a/sys/arch/vax/vax/intvec.s b/sys/arch/vax/vax/intvec.s index 71bda9563ba..8264eef81de 100644 --- a/sys/arch/vax/vax/intvec.s +++ b/sys/arch/vax/vax/intvec.s @@ -1,8 +1,8 @@ -/* $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 @@ -31,13 +31,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /* All bugs are subject to removal without further notice */ - +#include "assym.h" -#include -#include -#include +#include "ppp.h" +#include "bridge.h" #define ENTRY(name) \ .text ; \ @@ -63,23 +61,18 @@ ENTRY(namn) ; \ 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: /* @@ -89,81 +82,74 @@ _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 @@ -175,10 +161,17 @@ mcheck: .globl mcheck 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 @@ -201,50 +194,54 @@ L4: addl2 (sp)+,sp # remove info pushed on stack 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) @@ -260,101 +257,70 @@ syscall: 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 @@ -378,7 +344,7 @@ _sret: movl (sp)+, fp rei sbifltmsg: - .asciz "SBI fault",0 + .asciz "SBI fault" #if VAX630 || VAX650 || VAX410 /* diff --git a/sys/arch/vax/vax/ka410.c b/sys/arch/vax/vax/ka410.c index 7be2a8e41e5..fa61b9294ed 100644 --- a/sys/arch/vax/vax/ka410.c +++ b/sys/arch/vax/vax/ka410.c @@ -1,5 +1,5 @@ -/* $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. @@ -37,6 +37,8 @@ #include #include #include +#include + #include #include @@ -48,82 +50,84 @@ #include #include #include +#include #include +#include -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 @@ -137,110 +141,7 @@ ka410_mchk(addr) 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 @@ -257,3 +158,15 @@ ka410_reboot(arg) 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); +} diff --git a/sys/arch/vax/vax/ka43.c b/sys/arch/vax/vax/ka43.c index 6dc632043c9..fadb67ffc80 100644 --- a/sys/arch/vax/vax/ka43.c +++ b/sys/arch/vax/vax/ka43.c @@ -1,5 +1,5 @@ -/* $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. @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -48,56 +49,40 @@ #include #include #include +#include #include #include -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, }; /* @@ -105,10 +90,9 @@ struct cpu_dep ka43_calls = { * 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 */ @@ -167,7 +151,7 @@ ka43_mchk(addr) /* * 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) { @@ -207,13 +191,15 @@ ka43_cache_init() 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() @@ -230,8 +216,6 @@ 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); } @@ -239,7 +223,7 @@ ka43_cache_reset() int ka43_cache_disable() { - int i, val; + int val; /* * first disable primary cache and clear error flags @@ -282,7 +266,6 @@ ka43_cache_invalidate() */ 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 */ } @@ -317,27 +300,24 @@ ka43_cache_enable() } 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); } @@ -346,72 +326,12 @@ ka43_conf(parent, self, aux) * 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 @@ -421,35 +341,32 @@ these unavailable pages. Only valid/available pages are counted in RPB. * 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"); } + diff --git a/sys/arch/vax/vax/ka46.c b/sys/arch/vax/vax/ka46.c new file mode 100644 index 00000000000..fa0b6b6e07b --- /dev/null +++ b/sys/arch/vax/vax/ka46.c @@ -0,0 +1,165 @@ +/* $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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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"); +} diff --git a/sys/arch/vax/vax/ka48.c b/sys/arch/vax/vax/ka48.c new file mode 100644 index 00000000000..ae2c4bcfe1f --- /dev/null +++ b/sys/arch/vax/vax/ka48.c @@ -0,0 +1,166 @@ +/* $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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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"); +} diff --git a/sys/arch/vax/vax/ka49.c b/sys/arch/vax/vax/ka49.c new file mode 100644 index 00000000000..efd717d5b9d --- /dev/null +++ b/sys/arch/vax/vax/ka49.c @@ -0,0 +1,236 @@ +/* $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 +#include +#include +#include + +#include +#include +#include + +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"); +} diff --git a/sys/arch/vax/vax/ka630.c b/sys/arch/vax/vax/ka630.c index 8e54da3654f..a1d358db79a 100644 --- a/sys/arch/vax/vax/ka630.c +++ b/sys/arch/vax/vax/ka630.c @@ -1,5 +1,5 @@ -/* $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. @@ -40,61 +40,57 @@ #include #include #include +#include #include #include -#include #include -#include -#include #include -#include -#include #include #include -#include +#include 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 */ @@ -120,6 +116,7 @@ struct mc78032frame { int mc63_psl; /* trapped psl */ }; +int ka630_mchk(cmcf) caddr_t cmcf; { @@ -133,57 +130,16 @@ ka630_mchk(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() { @@ -197,6 +153,15 @@ ka630_reboot(arg) { ((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; } diff --git a/sys/arch/vax/vax/ka650.c b/sys/arch/vax/vax/ka650.c index f73a758d7b5..e0ffa4a5b72 100644 --- a/sys/arch/vax/vax/ka650.c +++ b/sys/arch/vax/vax/ka650.c @@ -1,5 +1,5 @@ -/* $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. @@ -55,38 +55,33 @@ #include #include #include -#include #include -#include - 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, }; @@ -95,90 +90,35 @@ struct cpu_dep ka650_calls = { * 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 @@ -344,7 +284,4 @@ ka650_reboot(arg) int arg; { ka650ssc_ptr->ssc_cpmbx = CPMB650_DOTHIS | CPMB650_REBOOT; - mtpr(GC_BOOT, PR_TXDB); - asm("movl %0,r5;halt"::"g"(arg)); } - diff --git a/sys/arch/vax/vax/ka670.c b/sys/arch/vax/vax/ka670.c new file mode 100644 index 00000000000..73e8525c872 --- /dev/null +++ b/sys/arch/vax/vax/ka670.c @@ -0,0 +1,221 @@ +/* $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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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"); +} + diff --git a/sys/arch/vax/vax/ka750.c b/sys/arch/vax/vax/ka750.c index 5c67d604ab2..10a03e81ab1 100644 --- a/sys/arch/vax/vax/ka750.c +++ b/sys/arch/vax/vax/ka750.c @@ -1,5 +1,5 @@ -/* $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. @@ -38,82 +38,77 @@ */ #include -#include #include #include -#include -#include - #include -#include -#include +#include #include +#include #include -#include -#include -#include -#include +#include 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; @@ -121,8 +116,6 @@ ka750_memmatch(parent, gcf, aux) return 1; } -extern volatile caddr_t mcraddr[]; - struct mcr750 { int mc_err; /* error bits */ int mc_inh; /* inhibit crd */ @@ -144,10 +137,10 @@ struct mcr750 { /* 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; @@ -259,103 +252,19 @@ ka750_mchk(cmcf) } 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); } diff --git a/sys/arch/vax/vax/ka780.c b/sys/arch/vax/vax/ka780.c index 4cbb6dcf6a0..c69f6cf62ea 100644 --- a/sys/arch/vax/vax/ka780.c +++ b/sys/arch/vax/vax/ka780.c @@ -1,5 +1,5 @@ -/* $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. @@ -40,45 +40,78 @@ */ #include -#include #include #include -#include -#include - -#include -#include -#include -#include -#include #include #include +#include +#include -#include -#include - -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 */ }; /* @@ -130,12 +163,17 @@ struct mcr780 { /* 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) { @@ -163,7 +201,7 @@ ka780_memenable(sa, osc) void ka780_memerr() { - extern struct cfdriver mem_cd; + extern struct cfdriver mem_cd; struct mem_softc *sc; register struct mcr780 *mcr; register int m; @@ -314,9 +352,7 @@ struct ka78x { }; void -ka780_conf(parent, self, aux) - struct device *parent, *self; - void *aux; +ka780_conf() { extern char cpu_model[]; struct ka78x *ka78 = (void *)&vax_cpudata; @@ -324,29 +360,12 @@ ka780_conf(parent, self, aux) /* 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); -} diff --git a/sys/arch/vax/vax/ka820.c b/sys/arch/vax/vax/ka820.c index 5bcca45fc38..27db9a89263 100644 --- a/sys/arch/vax/vax/ka820.c +++ b/sys/arch/vax/vax/ka820.c @@ -1,5 +1,5 @@ -/* $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. @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -57,30 +58,30 @@ #include #include #include +#include -#include -#include +#include +#include + +#include 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 = { @@ -90,79 +91,26 @@ 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; @@ -175,9 +123,10 @@ ka820_attach(parent, self, aux) { 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", @@ -190,10 +139,27 @@ ka820_attach(parent, self, aux) 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. */ @@ -203,7 +169,13 @@ struct ms820regs { 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. */ @@ -238,12 +210,13 @@ struct ms820regs { #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 = { @@ -251,17 +224,18 @@ 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; @@ -272,71 +246,67 @@ ms820_attach(parent, self, aux) 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); } } @@ -402,7 +372,9 @@ ka820_mchk(cmcf) /* * Receive a character from logical console. */ -rxcdintr() +void +rxcdintr(arg) + int arg; { register int c = mfpr(PR_RXCD); diff --git a/sys/arch/vax/vax/ka860.c b/sys/arch/vax/vax/ka860.c index 4aefc7bf30e..8c37d93693b 100644 --- a/sys/arch/vax/vax/ka860.c +++ b/sys/arch/vax/vax/ka860.c @@ -1,5 +1,5 @@ -/* $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. @@ -37,15 +37,13 @@ /* * VAX 8600 specific routines. + * Also contains abus spec's and memory init routines. */ #include #include #include -#include -#include - #include #include #include @@ -53,29 +51,28 @@ #include #include -struct ioa *ioa; +#include -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, }; /* @@ -127,15 +124,6 @@ struct cpu_dep ka860_calls = { #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() @@ -270,35 +258,6 @@ ka86_mchk(cmcf) 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, @@ -308,27 +267,151 @@ struct ka86 { }; 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); +} diff --git a/sys/arch/vax/vax/locore.c b/sys/arch/vax/vax/locore.c index 960d2d04b2d..b1b6e3fdf5f 100644 --- a/sys/arch/vax/vax/locore.c +++ b/sys/arch/vax/vax/locore.c @@ -1,7 +1,7 @@ -/* $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 @@ -34,45 +34,31 @@ #include -#include #include #include #include +#include #include -#include - #include #include #include #include #include +#include #include #include 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; @@ -80,9 +66,14 @@ extern struct cpu_dep ka750_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 @@ -93,133 +84,126 @@ extern struct cpu_dep ka650_calls; 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: @@ -227,8 +211,30 @@ start() 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; /* diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c index 8c7bde72a14..f75157006f2 100644 --- a/sys/arch/vax/vax/machdep.c +++ b/sys/arch/vax/vax/machdep.c @@ -1,8 +1,8 @@ -/* $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. @@ -46,15 +46,14 @@ * @(#)machdep.c 7.16 (Berkeley) 6/3/91 */ +#include #include #include #include #include #include #include -#include #include -#include #include #include #include @@ -66,6 +65,14 @@ #include #include #include +#include +#include + +#include + +#include +#include + #ifdef SYSVMSG #include #endif @@ -76,21 +83,21 @@ #include #endif -#include - #include #include #ifdef INET #include -#include #include #endif +#ifdef NETATALK +#include +#endif #ifdef NS #include #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 #include @@ -112,47 +119,32 @@ #include #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 */ char machine_arch[] = MACHINE_ARCH; /* from */ 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 @@ -163,22 +155,22 @@ cpu_startup() 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); @@ -190,32 +182,37 @@ cpu_startup() * 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 buffers get (base+1) physical pages @@ -224,155 +221,54 @@ cpu_startup() * 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. @@ -393,12 +289,6 @@ dumpconf() dumplo = btodb(CLBYTES); } -void -cpu_initclocks() -{ - (*dep_call->cpu_clock)(); -} - int cpu_sysctl(a, b, c, d, e, f, g) int *a; @@ -420,10 +310,26 @@ setstatclockrate(hzrate) 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(); @@ -437,15 +343,17 @@ sys_sigreturn(p, v, retval) 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)) || @@ -456,7 +364,8 @@ sys_sigreturn(p, v, retval) 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; @@ -482,105 +391,74 @@ sendsig(catcher, sig, mask, code, type, val) 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(); @@ -588,21 +466,12 @@ boot(howto /* , bootstr */) * 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 (;;) ; @@ -615,9 +484,8 @@ boot(howto /* , bootstr */) */ 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 @@ -633,13 +501,14 @@ boot(howto /* , bootstr */) * 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) @@ -647,103 +516,22 @@ boot(howto /* , bootstr */) 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) @@ -753,12 +541,16 @@ dumpsys() * 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"); @@ -782,32 +574,6 @@ dumpsys() } } -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; @@ -821,7 +587,7 @@ process_read_regs(p, regs) regs->sp = tf->sp; regs->pc = tf->pc; regs->psl = tf->psl; - return (0); + return 0; } int @@ -837,7 +603,7 @@ process_write_regs(p, regs) tf->sp = regs->sp; tf->pc = regs->pc; tf->psl = regs->psl; - return (0); + return 0; } int @@ -851,10 +617,10 @@ process_set_pc(p, addr) 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); } @@ -880,8 +646,146 @@ process_sstep(p, sstep) 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); +} + diff --git a/sys/arch/vax/vax/mem.c b/sys/arch/vax/vax/mem.c index ba6a217bbec..028ee19e024 100644 --- a/sys/arch/vax/vax/mem.c +++ b/sys/arch/vax/vax/mem.c @@ -1,5 +1,5 @@ -/* $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. @@ -38,7 +38,7 @@ * 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 */ /* @@ -58,7 +58,7 @@ #include -extern unsigned int vmmap, avail_end; +extern unsigned int avail_end; caddr_t zeropage; int mmopen __P((dev_t, int, int)); @@ -102,23 +102,11 @@ mmrw(dev, uio, flags) 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) { @@ -134,24 +122,17 @@ mmrw(dev, uio, flags) 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); @@ -183,17 +164,11 @@ mmrw(dev, uio, flags) } 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); } @@ -203,17 +178,16 @@ mmmmap(dev, off, prot) 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); } diff --git a/sys/arch/vax/vax/pmap.c b/sys/arch/vax/vax/pmap.c index e763d966d63..b1a8974b201 100644 --- a/sys/arch/vax/vax/pmap.c +++ b/sys/arch/vax/vax/pmap.c @@ -1,7 +1,7 @@ -/* $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 @@ -34,15 +34,18 @@ #include #include #include +#include #include #include -#include #include #include +#include -#include -#include -#include +#ifdef PMAPDEBUG +#include +#endif + +#include #include #include @@ -52,71 +55,75 @@ #include #include -extern int bufcalc __P((void)); +#include +#include +#include + -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)<> 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(). @@ -127,25 +134,10 @@ vm_offset_t virtual_avail, virtual_end; /* Available virtual memory */ 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, @@ -154,169 +146,281 @@ pmap_bootstrap() * 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. @@ -326,21 +430,62 @@ void 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. @@ -356,7 +501,7 @@ pmap_destroy(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; @@ -365,95 +510,308 @@ if(startpmapdebug)printf("pmap_destroy: pmap %x\n",pmap); 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 * @@ -464,568 +822,524 @@ pmap_bootstrap_alloc(size) #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>PGSHIFT)|kernel_prot[prot]|PG_V; + (uint)pentry= (((uint)(virtuell)>>VAX_PGSHIFT)*4)+(uint)Sysmap; + for(count=pstart;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)<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(ipm_pcb->P1LR) - start=((pmap->pm_pcb->P1LR)<>PGSHIFT; - if(ipm_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> 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); } diff --git a/sys/arch/vax/vax/rootfil.c b/sys/arch/vax/vax/rootfil.c index e4f4db44a26..38a919040dc 100644 --- a/sys/arch/vax/vax/rootfil.c +++ b/sys/arch/vax/vax/rootfil.c @@ -1,4 +1,4 @@ -/* $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 $ */ /* @@ -56,11 +56,13 @@ #include #include #include +#include #include #include #include "hp.h" #include "ra.h" +#include "sd.h" #define DOSWAP /* Change swdevt, argdev, and dumpdev too */ #ifdef MAJA @@ -79,17 +81,17 @@ extern dev_t rootdev, dumpdev; 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); @@ -111,11 +113,17 @@ setroot() 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); /* diff --git a/sys/arch/vax/vax/sbi.c b/sys/arch/vax/vax/sbi.c index 872498bced6..9b9c3767415 100644 --- a/sys/arch/vax/vax/sbi.c +++ b/sys/arch/vax/vax/sbi.c @@ -1,5 +1,5 @@ -/* $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. @@ -30,6 +30,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * Still to do: Write all SBI error handling. + */ + #include #include #include @@ -40,7 +44,7 @@ #include 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 @@ -50,12 +54,11 @@ sbi_print(aux, name) { 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); @@ -68,14 +71,13 @@ sbi_print(aux, 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 @@ -83,37 +85,36 @@ sbi_attach(parent, self, aux) 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 }; - diff --git a/sys/arch/vax/vax/scb.c b/sys/arch/vax/vax/scb.c new file mode 100644 index 00000000000..684e943e987 --- /dev/null +++ b/sys/arch/vax/vax/scb.c @@ -0,0 +1,163 @@ +/* $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 +#include +#include + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/sys/arch/vax/vax/sgmap.c b/sys/arch/vax/vax/sgmap.c new file mode 100644 index 00000000000..befde02b503 --- /dev/null +++ b/sys/arch/vax/vax/sgmap.c @@ -0,0 +1,329 @@ +/* $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 +#include +#include +#include +#include + +#include + +#include +#include + +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; +} diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s index 79775c5fb74..53cbee8332f 100644 --- a/sys/arch/vax/vax/subr.s +++ b/sys/arch/vax/vax/subr.s @@ -1,5 +1,5 @@ -/* $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. @@ -31,20 +31,59 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /* All bugs are subject to removal without further notice */ - - -#include -#include +#include -#include -#include -#include -#include +#include "assym.h" +#ifdef COMPAT_ULTRIX +#include +#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 @@ -52,50 +91,48 @@ _sigcode: pushr $0x3f 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 @@ -117,137 +154,32 @@ _badaddr: .word 0x0 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. @@ -256,7 +188,7 @@ _bzero: .globl _bzero _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 @@ -270,3 +202,264 @@ _longjmp:.word 0 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 diff --git a/sys/arch/vax/vax/swapgeneric.c b/sys/arch/vax/vax/swapgeneric.c index 8bb544dbb29..8fcd9bf6050 100644 --- a/sys/arch/vax/vax/swapgeneric.c +++ b/sys/arch/vax/vax/swapgeneric.c @@ -1,4 +1,4 @@ -/* $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 $ */ /*- @@ -73,7 +73,7 @@ struct swdevt swdevt[] = { 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; diff --git a/sys/arch/vax/vax/trap.c b/sys/arch/vax/vax/trap.c index fd7e1c5131c..22e0648a8e6 100644 --- a/sys/arch/vax/vax/trap.c +++ b/sys/arch/vax/vax/trap.c @@ -1,6 +1,5 @@ -/* $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. @@ -32,9 +31,6 @@ */ /* All bugs are subject to removal without further notice */ - - - #include #include #include @@ -53,6 +49,7 @@ #include #include #include +#include #ifdef DDB #include @@ -62,48 +59,12 @@ #include #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", @@ -127,298 +88,242 @@ char *traptypes[]={ }; 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 @@ -426,38 +331,41 @@ syscall(frame) 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)) @@ -467,18 +375,40 @@ if(startsysc)printf("trap syscall %s pc %x, psl %x, sp %x, pid %d, frame %x\n", 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: @@ -493,7 +423,7 @@ bad: return; case ERESTART: - exptr->pc = exptr->pc-2; + exptr->pc -= (exptr->code > 63 ? 4 : 2); break; default: @@ -501,47 +431,31 @@ bad: 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); -} diff --git a/sys/arch/vax/vax/vm_machdep.c b/sys/arch/vax/vax/vm_machdep.c index 1e25254e5a9..2bfc0fe52f1 100644 --- a/sys/arch/vax/vax/vm_machdep.c +++ b/sys/arch/vax/vax/vm_machdep.c @@ -1,5 +1,5 @@ -/* $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. @@ -31,8 +31,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /* All bugs are subject to removal without further notice */ - #include #include #include @@ -78,17 +76,29 @@ pagemove(from, to, size) 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. @@ -103,36 +113,35 @@ cpu_fork(p1, p2, stack, stacksize) 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; @@ -155,7 +164,6 @@ cpu_fork(p1, p2, stack, stacksize) nyproc->R[1] = 1; return; /* Child is ready. Parent, return! */ - } /* @@ -186,7 +194,7 @@ cpu_set_kpc(p, pc, arg) 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; @@ -195,200 +203,12 @@ cpu_set_kpc(p, pc, arg) 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;ip_addr->u_pcb.iftrap; - - asm("movl $Lstr,(%0)":: "r"(addr)); - for(i=0;iep_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 @@ -401,91 +221,6 @@ sys_sysarch(p, v, retval) 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 @@ -504,14 +239,14 @@ cpu_coredump(p, vp, cred, chdr) 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; @@ -521,127 +256,54 @@ cpu_coredump(p, vp, cred, chdr) 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