From 7dc46dfff1a5ea70803d5b9978f4ce1fe3e233c4 Mon Sep 17 00:00:00 2001 From: rahnds Date: Mon, 20 Mar 2000 07:05:52 +0000 Subject: [PATCH] add first version of bus_dma for powerpc. changes to trap handler to print out better information for jump to 0 bugs. changes to pmap.c and machdep.c to debug a duplicate memory region bug occasionally observed on imac with compressed kernels. --- sys/arch/powerpc/powerpc/dma.c | 250 +++++++++++++++++++++++++ sys/arch/powerpc/powerpc/machdep.c | 26 +-- sys/arch/powerpc/powerpc/mainbus.c | 23 ++- sys/arch/powerpc/powerpc/ofw_machdep.c | 6 +- sys/arch/powerpc/powerpc/pmap.c | 34 +++- sys/arch/powerpc/powerpc/trap.c | 5 +- 6 files changed, 326 insertions(+), 18 deletions(-) create mode 100644 sys/arch/powerpc/powerpc/dma.c diff --git a/sys/arch/powerpc/powerpc/dma.c b/sys/arch/powerpc/powerpc/dma.c new file mode 100644 index 00000000000..faba6dd7f78 --- /dev/null +++ b/sys/arch/powerpc/powerpc/dma.c @@ -0,0 +1,250 @@ +/* $OpenBSD: dma.c,v 1.1 2000/03/20 07:05:52 rahnds Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 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 +#ifdef UVM +#include +#include +#else +#endif + +#include + +int +_dmamap_create(v, size, nsegments, maxsegsz, boundary, flags, dmamp) + void *v; + bus_size_t size; + int nsegments; + bus_size_t maxsegsz; + bus_size_t boundary; + int flags; + bus_dmamap_t *dmamp; +{ + register struct powerpc_bus_dmamap *map; + register size_t mapsize; + + mapsize = sizeof(struct powerpc_bus_dmamap) + + (sizeof(bus_dma_segment_t) * (nsegments - 1)); + MALLOC(map, struct powerpc_bus_dmamap *, mapsize, M_DEVBUF, + (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK); + if (!map) + return (ENOMEM); + + bzero(map, mapsize); + 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); + + *dmamp = map; + return (0); +} + +void +_dmamap_destroy(v, map) + void *v; + bus_dmamap_t map; +{ + free(map, M_DEVBUF); +} + +int +_dmamap_load(v, map, addr, size, p, flags) + void *v; + bus_dmamap_t map; + void *addr; + bus_size_t size; + struct proc *p; + int flags; +{ + panic("_dmamap_load: not implemented"); +} + +int +_dmamap_load_mbuf(v, map, m, flags) + void *v; + bus_dmamap_t map; + struct mbuf *m; + int flags; +{ + panic("_dmamap_load_mbuf: not implemented"); +} + +int +_dmamap_load_uio(v, map, uio, flags) + void *v; + bus_dmamap_t map; + struct uio *uio; + int flags; +{ + panic("_dmamap_load_uio: not implemented"); +} + +int +_dmamap_load_raw(v, map, segs, nsegs, size, flags) + void *v; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + panic("_dmamap_load_raw: not implemented"); +} + +void +_dmamap_unload(v, map) + void *v; + bus_dmamap_t map; +{ + panic("_dmamap_unload: not implemented"); +} + +void +_dmamap_sync(v, map, ops) + void *v; + bus_dmamap_t map; + bus_dmasync_op_t ops; +{ +#if 0 + __asm __volatile ("syncdma"); +#endif +} + +int +_dmamem_alloc(v, size, alignment, boundary, segs, nsegs, rsegs, flags) + void *v; + bus_size_t size, alignment, boundary; + bus_dma_segment_t *segs; + int nsegs; + int *rsegs; + int flags; +{ + vaddr_t va; + paddr_t spa, epa; + + size = round_page(size); + +#if defined(UVM) + va = uvm_pagealloc_contig(size, VM_MIN_KERNEL_ADDRESS, + VM_MAX_KERNEL_ADDRESS, NBPG); +#else + vm_page_alloc_memory(size, VM_MIN_KERNEL_ADDRESS, + VM_MAX_KERNEL_ADDRESS, + alignment, boundary, (void *)&va, nsegs, (flags & BUS_DMA_NOWAIT)); +#endif + if (va == NULL) + return (ENOMEM); + + segs[0].ds_addr = va; + segs[0].ds_len = size; + *rsegs = 1; + +#if 0 + /* XXX for now */ + for (epa = size + (spa = kvtop((caddr_t)va)); spa < epa; spa += NBPG) + pmap_changebit(spa, TLB_UNCACHEABLE, 0); +#endif + + return 0; + +} + +void +_dmamem_free(v, segs, nsegs) + void *v; + bus_dma_segment_t *segs; + int nsegs; +{ +#if defined (UVM) + uvm_km_free(kmem_map, segs[0].ds_addr, M_DEVBUF); +#else + kmem_free(kernel_map, segs[0].ds_addr, segs[0].ds_len); +#endif +} + +int +_dmamem_map(v, segs, nsegs, size, kvap, flags) + void *v; + bus_dma_segment_t *segs; + int nsegs; + size_t size; + caddr_t *kvap; + int flags; +{ + *kvap = (caddr_t)segs[0].ds_addr; + return 0; +} + +void +_dmamem_unmap(v, kva, size) + void *v; + caddr_t kva; + size_t size; +{ +} + +int +_dmamem_mmap(v, segs, nsegs, off, prot, flags) + void *v; + bus_dma_segment_t *segs; + int nsegs, off, prot, flags; +{ + panic("_dmamem_mmap: not implemented"); +} + +int +dma_cachectl(p, size) + caddr_t p; + int size; +{ +#if 0 + fdcache(HPPA_SID_KERNEL, (vaddr_t)p, size); + sync_caches(); +#endif + return 0; +} diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c index 0f134422d85..9588a2cc4b9 100644 --- a/sys/arch/powerpc/powerpc/machdep.c +++ b/sys/arch/powerpc/powerpc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.33 2000/02/22 19:27:58 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.34 2000/03/20 07:05:52 rahnds Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -72,7 +72,6 @@ #include #include -#include /* * Global variables used here and there */ @@ -171,7 +170,7 @@ initppc(startkernel, endkernel, args) * XXX We use the page just above the interrupt vector as * message buffer */ - initmsgbuf(0x3000, MSGBUFSIZE); + initmsgbuf((void *)0x3000, MSGBUFSIZE); where = 3; curpcb = &proc0paddr->u_pcb; @@ -198,15 +197,17 @@ where = 3; battable[0].batu = BATU(0x00000000); #if 1 - battable[1].batl = BATL(MPC106_V_ISA_IO_SPACE, BAT_I); - battable[1].batu = BATU(MPC106_P_ISA_IO_SPACE); + battable[1].batl = BATL(0x80000000, BAT_I); + battable[1].batu = BATU(0x80000000); segment8_mapped = 1; +#if 0 if(system_type == POWER4e) { /* Map ISA I/O */ addbatmap(MPC106_V_ISA_IO_SPACE, MPC106_P_ISA_IO_SPACE, BAT_I); battable[1].batl = BATL(0xbfffe000, BAT_I); battable[1].batu = BATU(0xbfffe000); } +#endif #endif /* @@ -360,6 +361,9 @@ where = 3; */ consinit(); +#if 0 + dump_avail(); +#endif #if NIPKDB > 0 /* * Now trap to IPKDB @@ -1173,6 +1177,12 @@ mapiodev(pa, len) spa = trunc_page(pa); off = pa - spa; size = round_page(off+len); + if ((pa >= 0x80000000) && ((pa+len) < 0x90000000)) { + extern int segment8_mapped; + if (segment8_mapped) { + return (void *)pa; + } + } #ifdef UVM va = vaddr = uvm_km_valloc(phys_map, size); #else @@ -1182,12 +1192,6 @@ mapiodev(pa, len) if (va == 0) return NULL; - if (pa >= 0x80000000 && pa+len < 0x90000000) { - extern int segment8_mapped; - if (segment8_mapped) { - return (void *)pa; - } - } for (; size > 0; size -= NBPG) { #if 0 pmap_enter(vm_map_pmap(phys_map), vaddr, spa, diff --git a/sys/arch/powerpc/powerpc/mainbus.c b/sys/arch/powerpc/powerpc/mainbus.c index 711720be72c..a836d5b2636 100644 --- a/sys/arch/powerpc/powerpc/mainbus.c +++ b/sys/arch/powerpc/powerpc/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.2 1998/08/22 18:31:59 rahnds Exp $ */ +/* $OpenBSD: mainbus.c,v 1.3 2000/03/20 07:05:53 rahnds Exp $ */ /* * Copyright (c) 1994, 1995 Carnegie-Mellon University. @@ -114,9 +114,28 @@ mbattach(parent, self, aux) } /* The following machines have a PCI bus */ - if (system_type != OFWMACH) { + if (system_type == APPL) { + char name[32]; + int node; + for (node = OF_child(OF_peer(0)); node; node= OF_peer(node)) { + bzero (name, sizeof(name)); + if (OF_getprop(node, "name", name, sizeof(name)) <= 0) + { + printf ("name not found on node %x\n"); + continue; + } + if (strcmp(name, "pci") == 0) { + nca.ca_name = "mpcpcibr"; + nca.ca_node = node; + nca.ca_bus = &sc->sc_bus; + config_found(self, &nca, mbprint); + } + + } + } else if (system_type != OFWMACH) { nca.ca_name = "mpcpcibr"; nca.ca_bus = &sc->sc_bus; + nca.ca_node = OF_finddevice("/pci"); config_found(self, &nca, mbprint); } } diff --git a/sys/arch/powerpc/powerpc/ofw_machdep.c b/sys/arch/powerpc/powerpc/ofw_machdep.c index b8d7cbb707d..a5011a20e46 100644 --- a/sys/arch/powerpc/powerpc/ofw_machdep.c +++ b/sys/arch/powerpc/powerpc/ofw_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_machdep.c,v 1.12 1999/11/09 00:20:42 rahnds Exp $ */ +/* $OpenBSD: ofw_machdep.c,v 1.13 2000/03/20 07:05:53 rahnds Exp $ */ /* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ /* @@ -327,6 +327,10 @@ ofwenablepcimemio(char *name, int qhandle) } #include /* HACK */ +#include +#include +#include +#include #include void ofwconprobe() diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c index eba267c40d1..86c1252c8d3 100644 --- a/sys/arch/powerpc/powerpc/pmap.c +++ b/sys/arch/powerpc/powerpc/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.14 2000/01/14 05:42:17 rahnds Exp $ */ +/* $OpenBSD: pmap.c,v 1.15 2000/03/20 07:05:53 rahnds Exp $ */ /* $NetBSD: pmap.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */ /* @@ -68,6 +68,22 @@ static u_int nextavail; static struct mem_region *mem, *avail; +#if 1 +void +dump_avail() +{ + int cnt; + struct mem_region *mp; + extern struct mem_region *avail; + + for (cnt = 0, mp = avail; mp->size; mp++) { + printf("memory region %x: start %x, size %x\n", + cnt, mp->size, mp->start); + cnt++; + } +} +#endif + /* * This is a cache of referenced/modified bits. * Bits herein are shifted by ATTRSHFT. @@ -296,8 +312,20 @@ pmap_bootstrap(kernelstart, kernelend) * Get memory. */ (fw->mem_regions)(&mem, &avail); - for (mp = mem; mp->size; mp++) + /* work around repeated entries bug */ + for (mp = mem; mp->size; mp++) { + if (mp[1].start == mp[0].start) { + int i; + i = 0; + do { + mp[0+i].size = mp[1+i].size; + mp[0+i].start = mp[1+i].start; + } while ( mp[0+(i++)].size != 0); + } + } + for (mp = mem; mp->size; mp++) { physmem += btoc(mp->size); + } /* * Count the number of available entries. @@ -1420,6 +1448,7 @@ addbatmap(u_int32_t vaddr, u_int32_t raddr, u_int32_t wimg) void pmap_activate(struct proc *p) { +#if 0 struct pcb *pcb = &p->p_addr->u_pcb; pmap_t pmap = p->p_vmspace->vm_map.pmap; @@ -1430,6 +1459,7 @@ pmap_activate(struct proc *p) pcb->pcb_pm = pmap; } curpcb=pcb; +#endif return; } /* ??? */ diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c index a11510662b1..d6fa8189f0d 100644 --- a/sys/arch/powerpc/powerpc/trap.c +++ b/sys/arch/powerpc/powerpc/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.16 2000/01/14 05:42:17 rahnds Exp $ */ +/* $OpenBSD: trap.c,v 1.17 2000/03/20 07:05:53 rahnds Exp $ */ /* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */ /* @@ -334,7 +334,8 @@ syscall_bad: default: brain_damage: - printf("trap type %x at %x\n", type, frame->srr0); + printf("trap type %x at %x lr %x\n", + type, frame->srr0, frame->lr); /* mpc_print_pci_stat(); */ -- 2.20.1