diff --git a/sys/arch/sgimips/sgimips/arcs.c b/sys/arch/sgimips/sgimips/arcs.c new file mode 100644 index 000000000000..d3393e060751 --- /dev/null +++ b/sys/arch/sgimips/sgimips/arcs.c @@ -0,0 +1,84 @@ +/* $NetBSD: arcs.c,v 1.1 2000/06/14 16:02:38 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 + +extern int db_max_line; + +const struct arcs_fv *ARCS; + +void arcsinit(void); +void arcssig(void); + +void +arcsinit(void) +{ + struct arcs_spb *spb; +int i; + + spb = (struct arcs_spb *)MIPS_PHYS_TO_KSEG0(0x00001000); + ARCS = spb->FirmwareVector; + + /* + * Default textport windows are only 20 lines high. + */ + db_max_line = 20; + + for (i = 0; i < 32; i++) { +#if 0 +printf("installing sig\n"); +#endif + } +} + +void +arcssig(void) +{ + printf("signal\n"); +} diff --git a/sys/arch/sgimips/sgimips/autoconf.c b/sys/arch/sgimips/sgimips/autoconf.c new file mode 100644 index 000000000000..2afde96746df --- /dev/null +++ b/sys/arch/sgimips/sgimips/autoconf.c @@ -0,0 +1,85 @@ +/* $NetBSD: autoconf.c,v 1.1 2000/06/14 16:02:41 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 "opt_ddb.h" + +#include +#include +#include +#include +#include + +#include + +static void findroot(struct device **, int *); + +void +cpu_configure() +{ + int s; + + s = splhigh(); + + if (config_rootfound("mainbus", "mainbus") == NULL) + panic("no mainbus found"); + + printf("biomask %02x netmask %02x ttymask %02x clockmask %02x\n", + biomask >> 8, netmask >> 8, ttymask >> 8, clockmask >> 8); + + _splnone(); +} + +void +cpu_rootconf() +{ + struct device *booted_device; + int booted_partition; + + findroot(&booted_device, &booted_partition); + + printf("boot device: %s\n", + booted_device ? booted_device->dv_xname : ""); + + setroot(booted_device, booted_partition); +} + +dev_t bootdev = 0; + +static void +findroot(devpp, partp) + struct device **devpp; + int *partp; +{ + return; +} diff --git a/sys/arch/sgimips/sgimips/bus.c b/sys/arch/sgimips/sgimips/bus.c new file mode 100644 index 000000000000..c1fd50890e73 --- /dev/null +++ b/sys/arch/sgimips/sgimips/bus.c @@ -0,0 +1,911 @@ +/* $NetBSD: bus.c,v 1.1 2000/06/14 16:02:42 soren Exp $ */ + +/* + * Copyright (c) 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 +#include + +#define _SGIMIPS_BUS_DMA_PRIVATE +#include +#include + +#include +#include + +#include + +#include +#include + +static int _bus_dmamap_load_buffer(bus_dmamap_t, void *, bus_size_t, + struct proc *, int, vaddr_t *, int *, int); + +struct sgimips_bus_dma_tag sgimips_default_bus_dma_tag = { + _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, +}; + +u_int8_t +bus_space_read_1(t, h, o) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; +{ + wbflush(); /* XXX ? */ + + switch (t) { + case 0: + return *(volatile u_int8_t *)(h + o); + case 1: /* XXX HPC */ + return *(volatile u_int8_t *)(h + (o << 2) + 3); + case 2: /* mem */ + case 4: /* I/O */ + return *(volatile u_int8_t *)(h + (o | 3) - (o & 3)); + case 3: /* mace devices */ + return *(volatile u_int8_t *)(h + (o << 8) + 7); + default: + panic("no bus tag"); + } +} + +void +bus_space_write_1(t, h, o, v) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int8_t v; +{ + switch (t) { + case 0: + *(volatile u_int8_t *)(h + o) = v; + break; + case 1: /* XXX HPC */ + *(volatile u_int8_t *)(h + (o << 2) + 3) = v; + break; + case 2: /* mem */ + case 4: /* I/O */ + *(volatile u_int8_t *)(h + (o | 3) - (o & 3)) = v; + break; + case 3: /* mace devices */ + *(volatile u_int8_t *)(h + (o << 8) + 7) = v; + break; + default: + panic("no bus tag"); + } + + wbflush(); /* XXX */ +} + +u_int16_t +bus_space_read_2(t, h, o) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; +{ + wbflush(); /* XXX ? */ + + switch (t) { + case 0: + return *(volatile u_int16_t *)(h + o); + case 1: /* XXX HPC */ + return *(volatile u_int16_t *)(h + (o << 2) + 1); + case 2: /* mem */ + return *(volatile u_int16_t *)(h + (o | 2) - (o & 3)); + case 4: /* I/O */ + return bswap16(*(volatile u_int16_t *)(h + (o | 2) - (o & 3))); + default: + panic("no bus tag"); + } +} + +void +bus_space_write_2(t, h, o, v) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t v; +{ + switch (t) { + case 0: + *(volatile u_int16_t *)(h + o) = v; + break; + case 1: /* XXX HPC */ + *(volatile u_int16_t *)(h + (o << 2) + 1) = v; + break; + case 2: /* mem */ + *(volatile u_int16_t *)(h + (o | 2) - (o & 3)) = v; + break; + case 4: /* I/O */ + *(volatile u_int16_t *)(h + (o | 2) - (o & 3)) = bswap16(v); + break; + default: + panic("no bus tag"); + } + + wbflush(); /* XXX */ +} + +int +bus_space_map(t, bpa, size, flags, bshp) + bus_space_tag_t t; + bus_addr_t bpa; + bus_size_t size; + int flags; + bus_space_handle_t *bshp; +{ + int cacheable = flags & BUS_SPACE_MAP_CACHEABLE; + + if (cacheable) + *bshp = MIPS_PHYS_TO_KSEG0(bpa); + else + *bshp = MIPS_PHYS_TO_KSEG1(bpa); + +/* + * XXX + */ + +#define PCI_LOW_MEMORY 0x1A000000 +#define PCI_LOW_IO 0x18000000 + + /* XXX O2 */ + if (bpa > 0x80000000 && bpa < 0x82000000) + *bshp = MIPS_PHYS_TO_KSEG1(PCI_LOW_MEMORY + (bpa & 0xfffffff)); + if (bpa < 0x00010000) + *bshp = MIPS_PHYS_TO_KSEG1(PCI_LOW_IO + bpa); + + + return 0; +} + +int +bus_space_alloc(t, rstart, rend, size, alignment, boundary, flags, bpap, bshp) + bus_space_tag_t t; + bus_addr_t rstart, rend; + bus_size_t size, alignment, boundary; + int flags; + bus_addr_t *bpap; + bus_space_handle_t *bshp; +{ + panic("bus_space_alloc: not implemented"); +} + +void +bus_space_free(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + panic("bus_space_free: not implemented"); +} + +void +bus_space_unmap(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + return; +} + +int +bus_space_subregion(t, bsh, offset, size, nbshp) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t offset, size; + bus_space_handle_t *nbshp; +{ + + *nbshp = bsh + offset; + return 0; +} + +/* + * 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 sgimips_bus_dmamap *map; + void *mapstore; + size_t mapsize; + + /* + * Allcoate 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 notifes 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 sgimips_bus_dmamap) + + (sizeof(bus_dma_segment_t) * (nsegments - 1)); + if ((mapstore = malloc(mapsize, M_DMAMAP, + (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) + return ENOMEM; + + bzero(mapstore, mapsize); + map = (struct sgimips_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; + 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; +{ + + free(map, M_DMAMAP); +} +extern paddr_t kvtophys(vaddr_t); /* XXX */ + +/* + * Utility function to load a linear buffer. lastaddrp holds state + * between invocations (for multiple-buffer loads). segp contains + * the starting segment on entrance, and the ending segment on exit. + * first indicates if this is the first invocation of this function. + */ +int +_bus_dmamap_load_buffer(map, buf, buflen, p, flags, + lastaddrp, segp, first) + bus_dmamap_t map; + void *buf; + bus_size_t buflen; + struct proc *p; + int flags; + vaddr_t *lastaddrp; + int *segp; + int first; +{ + bus_size_t sgsize; + bus_addr_t curaddr, lastaddr, baddr, bmask; + vaddr_t vaddr = (vaddr_t)buf; + int seg; + + lastaddr = *lastaddrp; + bmask = ~(map->_dm_boundary - 1); + + for (seg = *segp; buflen > 0 ; ) { + /* + * Get the physical address for this segment. + */ + if (p != NULL) + (void) pmap_extract(p->p_vmspace->vm_map.pmap, + vaddr, &curaddr); + else + curaddr = kvtophys(vaddr); + + /* + * 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 + * the previous segment if possible. + */ + if (first) { + map->dm_segs[seg].ds_addr = curaddr; + map->dm_segs[seg].ds_len = sgsize; + map->dm_segs[seg]._ds_vaddr = vaddr; + 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; + map->dm_segs[seg]._ds_vaddr = vaddr; + } + } + + 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; +} + +/* + * Common function for loading a direct-mapped DMA map with a linear + * buffer. + */ +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; +{ + vaddr_t lastaddr; + int seg, 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; + + seg = 0; + error = _bus_dmamap_load_buffer(map, buf, buflen, + p, flags, &lastaddr, &seg, 1); + if (error == 0) { + map->dm_mapsize = buflen; + map->dm_nsegs = seg + 1; + + /* + * For linear buffers, we support marking the mapping + * as COHERENT. + * + * XXX Check TLB entries for cache-inhibit bits? + */ + if (buf >= (void *)MIPS_KSEG1_START && + buf < (void *)MIPS_KSEG2_START) + map->_dm_flags |= SGIMIPS_DMAMAP_COHERENT; + } + 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; +{ + vaddr_t lastaddr; + int seg, error, first; + struct mbuf *m; + + /* + * 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 + + 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(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; + } + 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; +{ + vaddr_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(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. + */ +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 + * chipset-specific DMA map unload functions. + */ +void +_bus_dmamap_unload(t, map) + bus_dma_tag_t t; + bus_dmamap_t map; +{ + + /* + * No resources to free; just mark the mappings as + * invalid. + */ + map->dm_mapsize = 0; + map->dm_nsegs = 0; + map->_dm_flags &= ~SGIMIPS_DMAMAP_COHERENT; +} + +/* + * Common function for DMA map synchronization. May be called + * by chipset-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; +{ + bus_size_t minlen; + bus_addr_t addr; + int i; + + /* + * Mising PRE and POST operations is not allowed. + */ + if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 && + (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0) + panic("_bus_dmamap_sync: mix PRE and POST"); + +#ifdef DIAGNOSTIC + if (offset >= map->dm_mapsize) + panic("_bus_dmamap_sync: bad offset %lu (map size is %lu)", + offset, map->dm_mapsize); + if (len == 0 || (offset + len) > map->dm_mapsize) + panic("_bus_dmamap_sync: bad length"); +#endif + + /* + * Flush the write buffer. + */ + wbflush(); + + /* + * If the mapping is of COHERENT DMA-safe memory, no cache + * flush is necessary. + */ + if (map->_dm_flags & SGIMIPS_DMAMAP_COHERENT) + return; + + /* + * No cache flushes are necessary if we're only doing + * POSTREAD or POSTWRITE (i.e. not doing PREREAD or PREWRITE). + */ + if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) == 0) + return; + + /* + * Flush data cache for PREREAD. This has the side-effect + * of invalidating the cache. Done at PREREAD since it + * causes the cache line(s) to be written back to memory. + * + * Flush data cache for PREWRITE, so that the contents of + * the data buffer in memory reflect reality. + * + * Given the test above, we know we're doing one of these + * two operations, so no additional tests are necessary. + */ + + for (i = 0; i < map->dm_nsegs && len != 0; i++) { + /* Find the beginning segment. */ + if (offset >= map->dm_segs[i].ds_len) { + offset -= map->dm_segs[i].ds_len; + continue; + } + + /* + * Now at the first segment to sync; nail + * each segment until we have exhausted the + * length. + */ + minlen = len < map->dm_segs[i].ds_len - offset ? + len : map->dm_segs[i].ds_len - offset; + + addr = map->dm_segs[i]._ds_vaddr; + +#ifdef BUS_DMA_DEBUG + printf("bus_dmamap_sync: flushing segment %d " + "(0x%lx..0x%lx) ...", i, addr + offset, + addr + offset + minlen - 1); +#endif +#if 1 + MachFlushDCache(addr + offset, minlen); +#endif +#if 0 + mips3_HitFlushDCache(map->dm_segs[i]._ds_vaddr + offset, len); +#endif +#if 0 + MachFlushCache(); +#endif + +#ifdef BUS_DMA_DEBUG + printf("\n"); +#endif + offset = 0; + len -= minlen; + } +} + +/* + * 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; +{ + extern paddr_t avail_start, avail_end; + vaddr_t curaddr, lastaddr; + psize_t high; + vm_page_t m; + struct pglist mlist; + int curseg, error; + + /* Always round the size. */ + size = round_page(size); + + high = avail_end - PAGE_SIZE; + + /* + * Allocate pages from the VM system. + */ + TAILQ_INIT(&mlist); + error = uvm_pglistalloc(size, avail_start, 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; + m = m->pageq.tqe_next; + + for (; m != NULL; m = m->pageq.tqe_next) { + curaddr = VM_PAGE_TO_PHYS(m); +#ifdef DIAGNOSTIC + if (curaddr < avail_start || curaddr >= high) { + printf("vm_page_alloc_memory returned non-sensical" + " address 0x%lx\n", curaddr); + panic("_bus_dmamem_alloc"); + } +#endif + 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; +} + +/* + * 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; + + /* + * 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; +{ + vaddr_t va; + bus_addr_t addr; + int curseg; + + /* + * If we're only mapping 1 segment, use KSEG0 or KSEG1, to avoid + * TLB thrashing. + */ + if (nsegs == 1) { + if (flags & BUS_DMA_COHERENT) + *kvap = (caddr_t)MIPS_PHYS_TO_KSEG1(segs[0].ds_addr); + else + *kvap = (caddr_t)MIPS_PHYS_TO_KSEG0(segs[0].ds_addr); + 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"); + pmap_enter(pmap_kernel(), va, addr, + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); + + /* XXX Do something about COHERENT here. */ + } + } + + 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 DIAGNOSTIC + if ((u_long)kva & PGOFSET) + panic("_bus_dmamem_unmap"); +#endif + + /* + * Nothing to do if we mapped it with KSEG0 or KSEG1 (i.e. + * not in KSEG2). + */ + if (kva >= (caddr_t)MIPS_KSEG0_START && + kva < (caddr_t)MIPS_KSEG2_START) + return; + + size = round_page(size); + uvm_km_free(kernel_map, (vaddr_t)kva, 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 + if (off >= segs[i].ds_len) { + off -= segs[i].ds_len; + continue; + } + + return mips_btop((caddr_t)segs[i].ds_addr + off); + } + + /* Page not found. */ + return -1; +} diff --git a/sys/arch/sgimips/sgimips/clock.c b/sys/arch/sgimips/sgimips/clock.c new file mode 100644 index 000000000000..69fd81986fb0 --- /dev/null +++ b/sys/arch/sgimips/sgimips/clock.c @@ -0,0 +1,70 @@ +/* $NetBSD: clock.c,v 1.1 2000/06/14 16:02:42 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 + +void cpu_initclocks(void); +void inittodr(time_t); +void resettodr(void); +void setstatclockrate(int); + +void +cpu_initclocks() +{ + return; +} + +void +inittodr(base) + time_t base; +{ + return; +} + +void +resettodr(void) +{ + return; +} + +void +setstatclockrate(arg) + int arg; +{ + return; +} diff --git a/sys/arch/sgimips/sgimips/conf.c b/sys/arch/sgimips/sgimips/conf.c new file mode 100644 index 000000000000..a69eb0a1c3bf --- /dev/null +++ b/sys/arch/sgimips/sgimips/conf.c @@ -0,0 +1,227 @@ +/* $NetBSD: conf.c,v 1.1 2000/06/14 16:02:43 soren Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)conf.c 8.2 (Berkeley) 11/14/93 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vnd.h" +#include "sd.h" +#include "st.h" +#include "ccd.h" +#include "md.h" +#include "ch.h" +#include "ss.h" +#include "cd.h" +#include "uk.h" +#include "raid.h" +#include "tun.h" +#include "pty.h" +#include "bpfilter.h" +#include "ipfilter.h" +#include "rnd.h" +#include "scsibus.h" +#include "wd.h" +bdev_decl(wd); +cdev_decl(wd); +#include "ca.h" +#include "zstty.h" +cdev_decl(zs); +#include "com.h" +cdev_decl(com); + +struct bdevsw bdevsw[] = +{ + bdev_notdef(), /* 0: */ + bdev_swap_init(1,sw), /* 1: swap pseudo-device */ + bdev_disk_init(NMD,md), /* 2: memory disk */ + bdev_disk_init(NCCD,ccd), /* 3: concatenated disk driver */ + bdev_disk_init(NVND,vnd), /* 4: vnode disk driver */ + bdev_disk_init(NRAID,raid), /* 5: RAIDframe */ + bdev_notdef(), /* 6: */ + bdev_notdef(), /* 7: */ + bdev_notdef(), /* 8: */ + bdev_notdef(), /* 9: */ + bdev_disk_init(NSD,sd), /* 10: SCSI disk */ + bdev_tape_init(NST,st), /* 11: SCSI tape */ + bdev_disk_init(NCD,cd), /* 12: SCSI CD-ROM */ + bdev_disk_init(NWD,wd), /* 13: ATA disk */ + bdev_disk_init(NCA,ca), /* 14: Compaq array */ + bdev_notdef(), /* 15: */ + bdev_notdef(), /* 16: */ + bdev_notdef(), /* 17: */ + bdev_notdef(), /* 18: */ + bdev_notdef(), /* 19: */ +}; +int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]); + +/* + * swapdev is a fake block device implemented in sw.c and only used + * internally to get to swstrategy. It cannot be provided to the + * users, because the swstrategy routine munches the b_dev and b_blkno + * entries before calling the appropriate driver. This would horribly + * confuse, e.g. the hashing routines. User access (e.g., for libkvm + * and ps) is provided through the /dev/drum character (raw) device. + */ +dev_t swapdev = makedev(0, 0); + +struct cdevsw cdevsw[] = +{ + cdev_cn_init(1,cn), /* 0: console */ + cdev_swap_init(1,sw), /* 1: /dev/drum (swap pseudo-device) */ + cdev_disk_init(NMD,md), /* 2: memory disk driver */ + cdev_disk_init(NVND,vnd), /* 3: vnode disk driver */ + cdev_disk_init(NCCD,ccd), /* 4: concatenated disk driver */ + cdev_disk_init(NRAID,raid), /* 5: RAIDframe disk driver */ + cdev_notdef(), /* 6: */ + cdev_notdef(), /* 7: */ + cdev_notdef(), /* 8: */ + cdev_notdef(), /* 9: */ + cdev_disk_init(NSD,sd), /* 10: SCSI disk */ + cdev_tape_init(NST,st), /* 11: SCSI tape */ + cdev_disk_init(NCD,cd), /* 12: SCSI CD-ROM */ + cdev_disk_init(NWD,wd), /* 13: ATA disk */ + cdev_disk_init(NCA,ca), /* 14: Compaq array */ + cdev_notdef(), /* 15: */ + cdev_notdef(), /* 16: */ + cdev_notdef(), /* 17: */ + cdev_notdef(), /* 18: */ + cdev_notdef(), /* 19: */ + cdev_mm_init(1,mm), /* 20: /dev/{null,mem,kmem,...} */ + cdev_ctty_init(1,ctty), /* 21: controlling terminal */ + cdev_tty_init(NPTY,pts), /* 22: pseudo-tty slave */ + cdev_ptc_init(NPTY,ptc), /* 23: pseudo-tty master */ + cdev_log_init(1,log), /* 24: /dev/klog */ + cdev_lkm_init(NLKM,lkm), /* 25: lkm */ + cdev_fd_init(1,filedesc), /* 26: file descriptor pseudo-device */ + cdev_bpftun_init(NBPFILTER,bpf),/* 27: Berkeley packet filter */ + cdev_bpftun_init(NTUN,tun), /* 28: network tunnel */ + cdev_ipf_init(NIPFILTER,ipl), /* 29: ipl */ + cdev_rnd_init(NRND,rnd), /* 30: random source pseudo-device */ + cdev_uk_init(NUK,uk), /* 31: SCSI unknown */ + cdev_scanner_init(NSS,ss), /* 32: SCSI scanner */ + cdev_ch_init(NCH,ch), /* 33: SCSI changer */ + cdev_scsibus_init(NSCSIBUS,scsibus), /* 34: SCSI bus */ + cdev_tty_init(NZSTTY,zs), /* 35: Zilog 8530 serial port */ + cdev_tty_init(NCOM,com), /* 36: com serial port */ + cdev_tty_init(1,arcs), /* 37: ARCS PROM console */ + cdev_notdef(), /* 38: */ + cdev_notdef(), /* 39: */ +}; +int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]); + +int mem_no = 20; /* Major device number of memory special file */ + +int +iskmemdev(dev) + dev_t dev; +{ + return (major(dev) == mem_no && minor(dev) < 2); +} + +int +iszerodev(dev) + dev_t dev; +{ + return (major(dev) == mem_no && minor(dev) == 12); +} + +static int chrtoblktbl[] = { + /* XXX This needs to be dynamic for LKMs. */ + /* VCHR */ /* VBLK */ + /* 0 */ NODEV, + /* 1 */ 1, + /* 2 */ 2, + /* 3 */ 3, + /* 4 */ 3, + /* 5 */ 5, + /* 6 */ NODEV, + /* 7 */ NODEV, + /* 8 */ NODEV, + /* 9 */ NODEV, + /* 10 */ 10, + /* 11 */ 11, + /* 12 */ 12, + /* 13 */ 13, + /* 14 */ 14, + /* 15 */ NODEV, + /* 16 */ NODEV, + /* 17 */ NODEV, + /* 18 */ NODEV, + /* 19 */ NODEV, + /* 20 */ NODEV, + /* 21 */ NODEV, + /* 22 */ NODEV, + /* 23 */ NODEV, + /* 24 */ NODEV, + /* 25 */ NODEV, + /* 26 */ NODEV, + /* 27 */ NODEV, + /* 28 */ NODEV, + /* 29 */ NODEV, + /* 30 */ NODEV, + /* 31 */ NODEV, + /* 32 */ NODEV, + /* 33 */ NODEV, + /* 34 */ NODEV, + /* 35 */ NODEV, + /* 37 */ NODEV, + /* 38 */ NODEV, + /* 39 */ NODEV, +}; + +dev_t +chrtoblk(dev) + dev_t dev; +{ + int blkmaj; + + if (major(dev) >= nchrdev) + return NODEV; + blkmaj = chrtoblktbl[major(dev)]; + if (blkmaj == NODEV) + return NODEV; + return (makedev(blkmaj, minor(dev))); +} diff --git a/sys/arch/sgimips/sgimips/console.c b/sys/arch/sgimips/sgimips/console.c new file mode 100644 index 000000000000..5c0361009e16 --- /dev/null +++ b/sys/arch/sgimips/sgimips/console.c @@ -0,0 +1,297 @@ +/* $NetBSD: console.c,v 1.1 2000/06/14 16:02:44 soren Exp $ */ + +/* + * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static void arcs_cnputc(dev_t, int); +static int arcs_cngetc(dev_t); +static int arcs_cnlookc(dev_t, int *); + +struct consdev arcs_cn = { + NULL, NULL, arcs_cngetc, arcs_cnputc, nullcnpollc, NULL, NODEV, + CN_NORMAL +}; + +struct callout arcs_ch = CALLOUT_INITIALIZER; + +void +consinit() +{ + arcs_cn.cn_dev = makedev(37, 0); + + cn_tab = &arcs_cn; + + return; +} + +static void +arcs_cnputc(dev, c) + dev_t dev; + int c; +{ + char ch = c; + u_int32_t count; + + ARCS->Write(ARCS_STDOUT, &ch, 1, &count); + + return; +} + +static int +arcs_cngetc(dev) + dev_t dev; +{ + char c; + u_int32_t count; + + ARCS->Read(ARCS_STDIN, &c, 1, &count); + + return c; +} + +static int +arcs_cnlookc(dev, cp) + dev_t dev; + int *cp; +{ + char c; + int32_t q; + u_int32_t count; + + q = ARCS->GetReadStatus(ARCS_STDIN); + + if (q == 0) { + ARCS->Read(ARCS_STDIN, &c, 1, &count); + *cp = c; + + return 1; + } + else { + return 0; + } +} + +static struct tty *arcs_tty[1]; + +void arcs_start(struct tty *); +void arcs_poll(void *); +int arcs_param(struct tty *, struct termios *); + +int +arcsopen(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int unit = minor(dev); + struct tty *tp; + int s; + int error = 0, setuptimeout = 0; + + s = spltty(); + + if (!arcs_tty[unit]) { + tp = arcs_tty[unit] = ttymalloc(); + tty_attach(tp); + } else + tp = arcs_tty[unit]; + + tp->t_oproc = arcs_start; + tp->t_param = arcs_param; + tp->t_dev = dev; + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_CARR_ON; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG | CLOCAL; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = 9600; + ttsetwater(tp); + + setuptimeout = 1; + } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { + splx(s); + return EBUSY; + } + + splx(s); + + error = (*linesw[tp->t_line].l_open)(dev, tp); + if (error == 0 && setuptimeout) { + callout_reset(&arcs_ch, 1, arcs_poll, tp); + } + return error; +} + +int +arcsclose(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int unit = minor(dev); + struct tty *tp = arcs_tty[unit]; + + callout_stop(&arcs_ch); + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + return 0; +} + +int +arcsread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + struct tty *tp = arcs_tty[minor(dev)]; + + return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + +int +arcswrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + struct tty *tp = arcs_tty[minor(dev)]; + + return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + +int +arcsioctl(dev, cmd, data, flag, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + int unit = minor(dev); + struct tty *tp = arcs_tty[unit]; + int error; + + 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; + + return ENOTTY; +} + +int +arcs_param(tp, t) + struct tty *tp; + struct termios *t; +{ + + return 0; +} + +void +arcs_start(tp) + struct tty *tp; +{ + int s; + + s = spltty(); + if (tp->t_state & (TS_TTSTOP | TS_BUSY)) + goto out; + if (tp->t_outq.c_cc <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_outq); + } + selwakeup(&tp->t_wsel); + } + tp->t_state |= TS_BUSY; + while (tp->t_outq.c_cc != 0) + arcs_cnputc(tp->t_dev, getc(&tp->t_outq)); + tp->t_state &= ~TS_BUSY; +out: + splx(s); +} + +void +arcsstop(tp, flag) + struct tty *tp; +{ + int s; + + s = spltty(); + if (tp->t_state & TS_BUSY) + if ((tp->t_state & TS_TTSTOP) == 0) + tp->t_state |= TS_FLUSH; + splx(s); +} + +void +arcs_poll(v) + void *v; +{ + struct tty *tp = v; + int c; + int l_r; + + while (arcs_cnlookc(tp->t_dev, &c)) { + if (tp->t_state & TS_ISOPEN) + l_r = (*linesw[tp->t_line].l_rint)(c, tp); + } + callout_reset(&arcs_ch, 1, arcs_poll, tp); +} + +struct tty * +arcstty(dev) + dev_t dev; +{ + + if (minor(dev) != 0) + panic("arcs_tty: bogus"); + + return arcs_tty[0]; +} diff --git a/sys/arch/sgimips/sgimips/cpu.c b/sys/arch/sgimips/sgimips/cpu.c new file mode 100644 index 000000000000..8d5723a1adbd --- /dev/null +++ b/sys/arch/sgimips/sgimips/cpu.c @@ -0,0 +1,100 @@ +/* $NetBSD: cpu.c,v 1.1 2000/06/14 16:02:44 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 cpu_match(struct device *, struct cfdata *, void *); +static void cpu_attach(struct device *, struct device *, void *); + +struct cfattach cpu_ca = { + sizeof(struct device), cpu_match, cpu_attach +}; + +static int +cpu_match(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + return 1; +} + +static void +cpu_attach(parent, self, aux) + struct device *parent; + struct device *self; + void *aux; +{ + struct mainbus_attach_args *ma = aux; + + if (ma->ma_arch == 32) + mips_L2CacheSize = 512 * 1024; /* XXX O2 */ + + printf(": "); + cpu_identify(); + + if (ma->ma_arch == 22) { /* XXX Indy */ + unsigned long tmp1, tmp2, tmp3; + + printf("cpu0: disabling auxiliary L2 cache\n"); + + __asm__ __volatile__(" + .set noreorder + .set mips3 + li %0, 0x1 + dsll %0, 31 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %1, %0 + mfc0 %2, $12 + nop; nop; nop; nop; + li %1, 0x80 + mtc0 %1, $12 + nop; nop; nop; nop; + sh $0, 0(%0) + mtc0 $0, $12 + nop; nop; nop; nop; + mtc0 %2, $12 + nop; nop; nop; nop; + .set mips2 + .set reorder + " : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); + } +} diff --git a/sys/arch/sgimips/sgimips/disksubr.c b/sys/arch/sgimips/sgimips/disksubr.c new file mode 100644 index 000000000000..411a15c583bb --- /dev/null +++ b/sys/arch/sgimips/sgimips/disksubr.c @@ -0,0 +1,168 @@ +/* $NetBSD: disksubr.c,v 1.1 2000/06/14 16:02:45 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 + +/* + * Attempt to read a disk label from a device using the indicated + * stategy routine. The label must be partly set up before this: + * secpercyl, secsize and anything required for a block i/o read + * operation in the driver's strategy/start routines must be + * filled in before calling us. + * + * Return buffer for use in signalling errors if requested. + * + * Returns null on success and an error string on failure. + */ + +char * +readdisklabel(dev, strat, lp, clp) + dev_t dev; + void (*strat)(struct buf *); + struct disklabel *lp; + struct cpu_disklabel *clp; +{ + struct buf *bp; + struct disklabel *dlp; + struct sgilabel *slp; + char block[512]; + int error; + int i; + + /* Minimal requirements for archetypal disk label. */ + if (lp->d_secsize == 0) + lp->d_secsize = DEV_BSIZE; + if (lp->d_secperunit == 0) + lp->d_secperunit = 0x1fffffff; + + /* Obtain buffer to probe drive with. */ + bp = geteblk((int)lp->d_secsize); + + /* Next, dig out the disk label. */ + bp->b_dev = dev; + bp->b_blkno = LABELSECTOR; + bp->b_cylinder = 0; + bp->b_bcount = lp->d_secsize; + bp->b_flags = B_BUSY | B_READ; + (*strat)(bp); + + /* If successful, locate disk label within block and validate. */ + error = biowait(bp); + if (error == 0) { + /* Save the whole block in case it has info we need. */ + memcpy(block, bp->b_un.b_addr, sizeof(block)); + } + bp->b_flags = B_INVAL | B_AGE | B_READ; + brelse(bp); + if (error != 0) + return "error reading disklabel"; + + /* Check for a NetBSD disk label. */ + dlp = (struct disklabel *) (block + LABELOFFSET); + if (dlp->d_magic == DISKMAGIC) { + if (dkcksum(dlp)) + return ("NetBSD disk label corrupted"); + *lp = *dlp; + return NULL; + } + + /* Check for a SGI label. */ + slp = (struct sgilabel *)block; + if (be32toh(slp->magic) != SGILABEL_MAGIC) + return "no disk label"; + /* + * XXX Calculate checksum. + */ + for (i = 0; i < MAXPARTITIONS; i++) { + /* XXX be32toh */ + lp->d_partitions[i].p_offset = slp->partitions[i].first; + lp->d_partitions[i].p_size = slp->partitions[i].blocks; + lp->d_partitions[i].p_fstype = FS_BSDFFS; + lp->d_partitions[i].p_fsize = 1024; + lp->d_partitions[i].p_frag = 8; + lp->d_partitions[i].p_cpg = 16; + + if (i == RAW_PART) + lp->d_partitions[i].p_fstype = FS_OTHER; + } + + lp->d_magic = DISKMAGIC; + lp->d_magic2 = DISKMAGIC; + lp->d_secsize = 512; + lp->d_npartitions = 16; + + lp->d_checksum = 0; + lp->d_checksum = dkcksum(lp); + + return NULL; +} + +int +setdisklabel(olp, nlp, openmask, clp) + struct disklabel *olp; + struct disklabel *nlp; + unsigned long openmask; + struct cpu_disklabel *clp; +{ + printf("SETDISKLABEL\n"); + + return 0; +} + +int +writedisklabel(dev, strat, lp, clp) + dev_t dev; + void (*strat)(struct buf *); + struct disklabel *lp; + struct cpu_disklabel *clp; +{ + printf("WRITEDISKLABEL\n"); + + return ENODEV; +} + +int +bounds_check_with_label(bp, lp, wlabel) + struct buf *bp; + struct disklabel *lp; + int wlabel; +{ + return 1; +} diff --git a/sys/arch/sgimips/sgimips/ip22.c b/sys/arch/sgimips/sgimips/ip22.c new file mode 100644 index 000000000000..23492987785a --- /dev/null +++ b/sys/arch/sgimips/sgimips/ip22.c @@ -0,0 +1,41 @@ +/* $NetBSD: ip22.c,v 1.1 2000/06/14 16:02:45 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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. + */ + +/* + * IP22: Indigo2, Indy + */ + +/* + * ip22_intr() etc. ... + */ diff --git a/sys/arch/sgimips/sgimips/ip27.c b/sys/arch/sgimips/sgimips/ip27.c new file mode 100644 index 000000000000..91f324ce80c3 --- /dev/null +++ b/sys/arch/sgimips/sgimips/ip27.c @@ -0,0 +1,37 @@ +/* $NetBSD: ip27.c,v 1.1 2000/06/14 16:02:46 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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. + */ + +/* + * IP27: Onyx2, Origin + */ diff --git a/sys/arch/sgimips/sgimips/ip32.c b/sys/arch/sgimips/sgimips/ip32.c new file mode 100644 index 000000000000..c4ca327b539f --- /dev/null +++ b/sys/arch/sgimips/sgimips/ip32.c @@ -0,0 +1,103 @@ +/* $NetBSD: ip32.c,v 1.1 2000/06/14 16:02:46 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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. + */ + +/* + * IP32: O2 + */ + +#include +#include + +#include +#include +#include +#include + +#define CRIME_NINTR 42 + +static struct { + int (*func)(void *); + void *arg; +} icu[CRIME_NINTR]; + +void * crime_intr_establish(int, int, int, int (*)(void *), void *); +int crime_intr(void *); + +void * +crime_intr_establish(irq, type, level, func, arg) + int irq; + int type; + int level; + int (*func)(void *); + void *arg; +{ + int i; + + for (i = 0; i <= CRIME_NINTR; i++) { + if (i == CRIME_NINTR) + panic("too many IRQs"); + + if (icu[i].func != NULL) + continue; + + icu[i].func = func; + icu[i].arg = arg; + break; + } + + return (void *)-1; +} + +int +crime_intr(arg) + void *arg; +{ + int i; + + for (i = 0; i < CRIME_NINTR; i++) { + if (icu[i].func == NULL) + return 0; + +#if 1 +if ( + (*icu[i].func)(icu[i].arg) +== 1) +return 1; +#else + (*icu[i].func)(icu[i].arg); +#endif + } + + return 0; +} diff --git a/sys/arch/sgimips/sgimips/machdep.c b/sys/arch/sgimips/sgimips/machdep.c new file mode 100644 index 000000000000..364319dce62d --- /dev/null +++ b/sys/arch/sgimips/sgimips/machdep.c @@ -0,0 +1,587 @@ +/* $NetBSD: machdep.c,v 1.1 2000/06/14 16:02:47 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 "opt_ddb.h" +#include "opt_execfmt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DDB +#include +#include +#include +#include +#ifndef DB_ELFSIZE +#error Must define DB_ELFSIZE! +#endif +#define ELFSIZE DB_ELFSIZE +#include +#endif + +#include + +/* For sysctl(3). */ +char machine[] = MACHINE; +char machine_arch[] = MACHINE_ARCH; +char cpu_model[] = "SGI"; + +/* Our exported CPU info; we can have only one. */ +struct cpu_info cpu_info_store; + +unsigned long cpuspeed; /* Approximate number of instructions per usec */ + +/* Maps for VM objects. */ +vm_map_t exec_map = NULL; +vm_map_t mb_map = NULL; +vm_map_t phys_map = NULL; + +int physmem; /* Total physical memory */ +int arcsmem; /* Memory used by the ARCS firmware */ + +phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; +int mem_cluster_cnt; + +void mach_init(int, char **, char **); + +extern void arcsinit(void); + +/* + * safepri is a safe priority for sleep to set for a spin-wait during + * autoconfiguration or after a panic. Used as an argument to splx(). + */ +int safepri = MIPS1_PSL_LOWIPL; + +extern caddr_t esym; +extern struct user *proc0paddr; + +/* + * Do all the stuff that locore normally does before calling main(). + * Process arguments passed to us by the ARCS firmware. + */ +void +mach_init(argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + unsigned long first, last; + caddr_t kernend, v, p0; + vsize_t size; + extern char edata[], end[]; + struct arcs_mem *mem; + char *cpufreq; + int i; + + /* + * Clear the BSS segment. + */ +#ifdef DDB + if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 && + ((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) { + esym = end; + esym += ((Elf_Ehdr *)end)->e_entry; + kernend = (caddr_t)mips_round_page(esym); + bzero(edata, end - edata); + } else +#endif + { + kernend = (caddr_t)mips_round_page(end); + memset(edata, 0, kernend - edata); + } + +#if 1 /* XXX Enable watchdog timer for testing kernels. */ + if ((unsigned long)kernend > 0x88000000) { /* XXX Indy */ + *(volatile u_int32_t *)0xbfa00004 |= 0x100; + /* Clear watchdog timer. */ + *(volatile u_int32_t *)0xbfa00014 = 0; + } else { + *(volatile u_int32_t *)0xb400000c |= 0x200; /* XXX O2 */ + *(volatile u_int32_t *)0xb4000034 = 0; /* prime timer */ + } +#endif + + arcsinit(); + consinit(); + +#if 1 /* skidt? */ + ARCS->FlushAllCaches(); +#endif + + cpufreq = ARCS->GetEnvironmentVariable("cpufreq"); + + if (cpufreq == 0) + panic("no $cpufreq"); + + cpuspeed = strtoul(cpufreq, NULL, 10) / 2; /* XXX MIPS3 only */ +#if 0 /* XXX create new mips/mips interface */ + mips3_cycle_count = strtoul(cpufreq, NULL, 10) * 5000000; +#endif + + uvm_setpagesize(); + + /* + * Copy exception-dispatch code down to exception vector. + * Initialize locore-function vector. + * Clear out the I and D caches. + */ + mips_vector_init(); + + boothowto = RB_SINGLE; + + for (i = 0; i < argc; i++) { +#if 0 + if (strcmp(argv[i], "OSLoadOptions=auto") == 0) { + boothowto &= ~RB_SINGLE; + } +#endif +#if 0 + printf("argv[%d]: %s\n", i, argv[i]); + /* delay(20000); */ /* give the user a little time.. */ +#endif + } + +#ifdef DDB + /* + * Initialize machine-dependent DDB commands, in case of early panic. + */ + db_machine_init(); + + if (boothowto & RB_KDB) + Debugger(); +#endif + + physmem = arcsmem = 0; + mem_cluster_cnt = 0; + mem = NULL; + + for (i = 0; i < VM_PHYSSEG_MAX; i++) { + mem = ARCS->GetMemoryDescriptor(mem); + + if (mem == NULL) + break; + + first = round_page(mem->BasePage * ARCS_PAGESIZE); + last = trunc_page(first + mem->PageCount * ARCS_PAGESIZE); + size = last - first; + + switch (mem->Type) { + case ARCS_MEM_CONT: + case ARCS_MEM_FREE: + if (last > MIPS_KSEG0_TO_PHYS(kernend)) + if (first < MIPS_KSEG0_TO_PHYS(kernend)) + first = MIPS_KSEG0_TO_PHYS(kernend); + + mem_clusters[mem_cluster_cnt].start = first; + mem_clusters[mem_cluster_cnt].size = size; + mem_cluster_cnt++; + +#if 1 +printf("memory 0x%lx 0x%lx\n", first, last); +#endif + uvm_page_physload(atop(first), atop(last), atop(first), + atop(last), VM_FREELIST_DEFAULT); + + break; + case ARCS_MEM_TEMP: + case ARCS_MEM_PERM: + arcsmem += btoc(size); + break; + case ARCS_MEM_EXCEP: + case ARCS_MEM_SPB: + case ARCS_MEM_BAD: + case ARCS_MEM_PROG: + break; + default: + panic("unknown memory descriptor %d type %d", + i, mem->Type); + } + + physmem += btoc(size); + + } + + if (mem_cluster_cnt == 0) + panic("no free memory descriptors found"); + + /* + * Initialize error message buffer (at end of core). + */ + mips_init_msgbuf(); + + /* + * Allocate space for proc0's USPACE. + */ + p0 = (caddr_t)pmap_steal_memory(USPACE, NULL, NULL); + proc0.p_addr = proc0paddr = (struct user *)p0; + proc0.p_md.md_regs = (struct frame *)(p0 + USPACE) - 1; + curpcb = &proc0.p_addr->u_pcb; + curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ + + /* + * Allocate space for system data structures. These data structures + * are allocated here instead of cpu_startup() because physical + * memory is directly addressable. We don't have to map these into + * virtual address space. + */ + size = (vsize_t)allocsys(NULL, NULL); + v = (caddr_t)pmap_steal_memory(size, NULL, NULL); + if ((allocsys(v, NULL) - v) != size) + panic("mach_init: table size inconsistency"); + + pmap_bootstrap(); +} + +/* + * Allocate memory for variable-sized tables. + */ +void +cpu_startup() +{ + unsigned i; + int base, residual; + vaddr_t minaddr, maxaddr; + vsize_t size; + char pbuf[9]; + + printf(version); + + format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); + printf("%s memory", pbuf); + + /* + * Allocate virtual address space for file I/O buffers. + * Note they are different than the array of headers, 'buf', + * and usually occupy more virtual memory than physical. + */ + size = MAXBSIZE * nbuf; + if (uvm_map(kernel_map, (vaddr_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("startup: cannot allocate VM for buffers"); + minaddr = (vaddr_t)buffers; + base = bufpages / nbuf; + residual = bufpages % nbuf; + for (i = 0; i < nbuf; i++) { + vsize_t curbufsize; + vaddr_t curbuf; + struct vm_page *pg; + + /* + * Each buffer has MAXBSIZE bytes of VM space allocated. Of + * that MAXBSIZE space, we allocate and map (base+1) pages + * for the first "residual" buffers, and then we allocate + * "base" pages for the rest. + */ + curbuf = (vaddr_t) buffers + (i * MAXBSIZE); + curbufsize = NBPG * ((i < residual) ? (base + 1) : base); + + while (curbufsize) { + pg = uvm_pagealloc(NULL, 0, NULL, 0); + if (pg == NULL) + panic("cpu_startup: not enough memory for " + "buffer cache"); + pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), + 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 = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, + 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); + /* + * Allocate a submap for physio. + */ + phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, + VM_PHYS_SIZE, 0, FALSE, NULL); + + /* + * (No need to allocate an mbuf cluster submap. Mbuf clusters + * are allocated via the pool allocator, and we use KSEG to + * map those pages.) + */ + + format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); + printf(", %s free", pbuf); + format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); + printf(", %s for ARCS", pbuf); + format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); + printf(", %s in %d buffers\n", pbuf, nbuf); + + /* + * Set up buffers, so they can be used to read disk labels. + */ + bufinit(); +} + +int +cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) + int *name; + u_int namelen; + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; + struct proc *p; +{ + /* All sysctl names at this level are terminal. */ + if (namelen != 1) + return ENOTDIR; + + switch (name[0]) { + default: + return EOPNOTSUPP; + } +} + +int waittime = -1; + +void +cpu_reboot(howto, bootstr) + int howto; + char *bootstr; +{ + /* Take a snapshot before clobbering any registers. */ + if (curproc) + savectx((struct user *)curpcb); + + if (cold) { + howto |= RB_HALT; + goto haltsys; + } + + /* If "always halt" was specified as a boot flag, obey. */ + if (boothowto & RB_HALT) + howto |= RB_HALT; + + boothowto = howto; + if ((howto & RB_NOSYNC) && (waittime < 0)) { + waittime = 0; + vfs_shutdown(); + + /* + * If we've been adjusting the clock, the todr + * will be out of synch; adjust it now. + */ + resettodr(); + } + + splhigh(); + + if (howto & RB_DUMP) + dumpsys(); + +haltsys: + doshutdownhooks(); + +#if 0 + if (howto & RB_POWERDOWN) { + printf("powering off...\n\n"); + ARCS->PowerDown(); + printf("WARNING: powerdown failed\n"); + } +#endif + + if (howto & RB_HALT) { + printf("halting...\n\n"); + ARCS->EnterInteractiveMode(); + } + + printf("rebooting...\n\n"); + ARCS->Reboot(); + + for (;;); +} + +void +microtime(tvp) + struct timeval *tvp; +{ + int s = splclock(); + static struct timeval lasttime; + + *tvp = time; + + /* + * Make sure that the time returned is always greater + * than that returned by the previous call. + */ + if (tvp->tv_sec == lasttime.tv_sec && + tvp->tv_usec <= lasttime.tv_usec && + (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { + tvp->tv_sec++; + tvp->tv_usec -= 1000000; + } + lasttime = *tvp; + splx(s); +} + +__inline void +delay(n) + unsigned long n; +{ + register long N = cpuspeed * n; + + while (--N > 0); +} + +void cpu_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t); + +extern int crime_intr(void *); /* XXX */ + +void +cpu_intr(status, cause, pc, ipending) + u_int32_t status; + u_int32_t cause; + u_int32_t pc; + u_int32_t ipending; +{ + struct clockframe cf; + int i; + unsigned long cycles; + uvmexp.intrs++; + +#if 0 +printf("crm: %llx %llx %llx %llx\n", *(volatile u_int64_t *)0xb4000010, + *(volatile u_int64_t *)0xb4000018, + *(volatile u_int64_t *)0xb4000020, + *(volatile u_int64_t *)0xb4000028); +#endif + +#if 1 + /* XXX soren Reset O2 watchdog timer */ + *(volatile u_int32_t *)0xb4000034 = 0; +#endif + +#if 1 +if ((*(volatile u_int32_t *)0xbf080004 & ~0x00100000) != 6) +panic("pcierr: %x %x", *(volatile u_int32_t *)0xbf080004, + *(volatile u_int32_t *)0xbf080000); +#endif + + *(volatile u_int64_t *)0xbf310018 = 0xffffffff; + *(volatile u_int64_t *)0xb4000018 = 0x000000000000ffff; + +#if 1 + if (ipending & 0x7800) + panic("interesting cpu_intr, pending 0x%x\n", ipending); +#endif + + + if (ipending & MIPS_INT_MASK_5) { + cycles = mips3_cycle_count(); + mips3_write_compare(cycles + 900000); /* XXX */ + + cf.pc = pc; + cf.sr = status; + + hardclock(&cf); + + cause &= ~MIPS_INT_MASK_5; + } +else + if (ipending & 0x7c00) + crime_intr(NULL); + + for (i = 0; i < 5; i++) { + if (ipending & (MIPS_INT_MASK_0 << i)) +#if 0 + if (intrtab[i].func != NULL) + if ((*intrtab[i].func)(intrtab[i].arg)) +#endif + cause &= ~(MIPS_INT_MASK_0 << i); + } + + _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + + /* 'softnet' interrupt */ + if (ipending & MIPS_SOFT_INT_MASK_1) { + clearsoftnet(); + uvmexp.softs++; + netintr(); + } + + /* 'softclock' interrupt */ + if (ipending & MIPS_SOFT_INT_MASK_0) { + clearsoftclock(); + uvmexp.softs++; + intrcnt[SOFTCLOCK_INTR]++; + softclock(); + } +} + +#define SPLSOFT MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1 + +#if 1 +u_int32_t biomask = 0x7f00; +u_int32_t netmask = 0x7f00; +u_int32_t ttymask = 0x7f00; +u_int32_t clockmask = 0xff00; +#endif diff --git a/sys/arch/sgimips/sgimips/mainbus.c b/sys/arch/sgimips/sgimips/mainbus.c new file mode 100644 index 000000000000..31ccdf962366 --- /dev/null +++ b/sys/arch/sgimips/sgimips/mainbus.c @@ -0,0 +1,157 @@ +/* $NetBSD: mainbus.c,v 1.1 2000/06/14 16:02:47 soren Exp $ */ + +/* + * Copyright (c) 2000 Soren S. Jorvang + * 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 for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 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 "locators.h" + +static int mainbus_match(struct device *, struct cfdata *, void *); +static void mainbus_attach(struct device *, struct device *, void *); +static int mainbus_search(struct device *, struct cfdata *, void *); +int mainbus_print(void *, const char *); + +static int atoi(char *); + +struct cfattach mainbus_ca = { + sizeof(struct device), mainbus_match, mainbus_attach +}; + +static int +mainbus_match(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + return 1; +} + +static void +mainbus_attach(parent, self, aux) + struct device *parent; + struct device *self; + void *aux; +{ + struct mainbus_attach_args *ma = aux; + struct arcs_component *root; + struct arcs_sysid *sysidp; + int i = 0; + + root = ARCS->GetChild(NULL); + printf(": %s", root->Identifier); + + sysidp = ARCS->GetSystemId(); + printf(" [%s, %s]", sysidp->Vendor, sysidp->Serial); + + printf("\n"); + + for (i = 0; root->Identifier[i] != '\0'; i++) { + if (root->Identifier[i] >= '0' && + root->Identifier[i] <= '9') { + ma->ma_arch = atoi(&root->Identifier[i]); + break; + } + } + + if (ma->ma_arch <= 0) + panic("invalid architecture"); + + config_search(mainbus_search, self, ma); +} + +static int +mainbus_search(parent, cf, aux) + struct device *parent; + struct cfdata *cf; + void *aux; +{ + struct mainbus_attach_args *ma = aux; + + do { + ma->ma_addr = cf->cf_loc[MAINBUSCF_ADDR]; + ma->ma_iot = 0; + ma->ma_ioh = MIPS_PHYS_TO_KSEG1(ma->ma_addr); + if ((*cf->cf_attach->ca_match)(parent, cf, ma) > 0) + config_attach(parent, cf, ma, mainbus_print); + } while (cf->cf_fstate == FSTATE_STAR); + + return 0; +} + +int +mainbus_print(aux, pnp) + void *aux; + const char *pnp; +{ + struct mainbus_attach_args *ma = aux; + + if (pnp != 0) + return QUIET; + + if (ma->ma_addr != MAINBUSCF_ADDR_DEFAULT) + printf(" addr 0x%lx", ma->ma_addr); + + return UNCONF; +} + +int +atoi(s) + char *s; +{ + int n, neg; + + n = 0; + neg = 0; + + while (*s == '-') { + s++; + neg = !neg; + } + + while (*s != '\0') { + if (*s < '0' && *s > '9') + break; + + n = (10 * n) + (*s - '0'); + s++; + } + + return (neg ? -n : n); +} diff --git a/sys/arch/sgimips/sgimips/md_root.c b/sys/arch/sgimips/sgimips/md_root.c new file mode 100644 index 000000000000..66e775237445 --- /dev/null +++ b/sys/arch/sgimips/sgimips/md_root.c @@ -0,0 +1,85 @@ +/* $NetBSD: md_root.c,v 1.1 2000/06/14 16:02:48 soren Exp $ */ + +/* + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. + * Copyright (c) 1995 Gordon W. Ross + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +#include "opt_mdsize.h" + +extern int boothowto; + +#ifndef MINIROOTSIZE +#define MINIROOTSIZE 512 +#endif + +#define ROOTBYTES (MINIROOTSIZE << DEV_BSHIFT) + +/* + * This array will be patched to contain a file-system image. + */ +u_int32_t md_root_size = ROOTBYTES; +char md_root_image[ROOTBYTES] = "|This is the root ramdisk!\n"; + +/* + * This is called during autoconfig. + */ +void +md_attach_hook(unit, md) + int unit; + struct md_conf *md; +{ + + if (unit == 0) { + /* Setup root ramdisk */ + md->md_addr = (caddr_t)md_root_image; + md->md_size = (size_t)md_root_size; + md->md_type = MD_KMEM_FIXED; + printf("md%d: internal %dK image area\n", unit, + ROOTBYTES / 1024); + } +} + +/* + * This is called during open (i.e. mountroot) + */ +void +md_open_hook(unit, md) + int unit; + struct md_conf *md; +{ + + if (unit == 0) { + /* The root ramdisk only works single-user. */ + boothowto |= RB_SINGLE; + } +}