[BACK]Return to mainbus.c CVS log [TXT][DIR] Up to [local] / sys / arch / mvme88k / dev

Annotation of sys/arch/mvme88k/dev/mainbus.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mainbus.c,v 1.22 2007/02/11 12:41:29 miod Exp $ */
                      2: /*
                      3:  * Copyright (c) 1998 Steve Murphree, Jr.
                      4:  * Copyright (c) 2004, Miodrag Vallat.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     23:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     25:  * POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27:
                     28: #include <sys/param.h>
                     29: #include <sys/systm.h>
                     30: #include <sys/reboot.h>
                     31: #include <sys/conf.h>
                     32: #include <sys/device.h>
                     33: #include <sys/disklabel.h>
                     34: #include <sys/extent.h>
                     35: #include <sys/malloc.h>
                     36:
                     37: #include <uvm/uvm_extern.h>
                     38:
                     39: #include <machine/bus.h>
                     40: #include <machine/autoconf.h>
                     41: #include <machine/cmmu.h>
                     42: #include <machine/cpu.h>
                     43:
                     44: #ifdef M88100
                     45: #include <machine/m8820x.h>
                     46: #endif
                     47: #ifdef MVME187
                     48: #include <machine/mvme187.h>
                     49: #endif
                     50: #ifdef MVME188
                     51: #include <machine/mvme188.h>
                     52: #endif
                     53: #ifdef MVME197
                     54: #include <machine/mvme197.h>
                     55: #endif
                     56:
                     57: void   mainbus_attach(struct device *, struct device *, void *);
                     58: int    mainbus_match(struct device *, void *, void *);
                     59: int    mainbus_print(void *, const char *);
                     60: int    mainbus_scan(struct device *, void *, void *);
                     61:
                     62: /*
                     63:  * bus_space routines for 1:1 obio mappings
                     64:  */
                     65:
                     66: int    mainbus_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *);
                     67: void   mainbus_unmap(bus_space_handle_t, bus_size_t);
                     68: int    mainbus_subregion(bus_space_handle_t, bus_size_t, bus_size_t,
                     69:            bus_space_handle_t *);
                     70: void   *mainbus_vaddr(bus_space_handle_t);
                     71:
                     72: const struct mvme88k_bus_space_tag mainbus_bustag = {
                     73:        mainbus_map,
                     74:        mainbus_unmap,
                     75:        mainbus_subregion,
                     76:        mainbus_vaddr
                     77: };
                     78:
                     79: bus_addr_t      bs_obio_start;
                     80: bus_addr_t      bs_obio_end;
                     81: struct extent  *bs_extent;
                     82:
                     83: /*
                     84:  * Obio (internal IO) space is mapped 1:1 (see pmap_bootstrap() for details).
                     85:  *
                     86:  * However, sram attaches as a child of mainbus, but does not reside in
                     87:  * internal IO space. As a result, we have to allow both 1:1 and regular
                     88:  * translations, depending upon the address to map.
                     89:  */
                     90:
                     91: int
                     92: mainbus_map(bus_addr_t addr, bus_size_t size, int flags,
                     93:     bus_space_handle_t *ret)
                     94: {
                     95:        vaddr_t map;
                     96:
                     97:        map = mapiodev((paddr_t)addr, size);
                     98:        if (map == NULL)
                     99:                return ENOMEM;
                    100:
                    101:        *ret = (bus_space_handle_t)map;
                    102:        return 0;
                    103: }
                    104:
                    105: void
                    106: mainbus_unmap(bus_space_handle_t handle, bus_size_t size)
                    107: {
                    108:        /* XXX what to do for non-obio mappings? */
                    109: }
                    110:
                    111: int
                    112: mainbus_subregion(bus_space_handle_t handle, bus_addr_t offset,
                    113:     bus_size_t size, bus_space_handle_t *ret)
                    114: {
                    115:        *ret = handle + offset;
                    116:        return (0);
                    117: }
                    118:
                    119: void *
                    120: mainbus_vaddr(bus_space_handle_t handle)
                    121: {
                    122:        return (void *)handle;
                    123: }
                    124:
                    125: /*
                    126:  * Map a range [pa, pa+size) in the given map to a kernel address
                    127:  * in iomap space.
                    128:  *
                    129:  * Note: To be flexible, I did not put a restriction on the alignment
                    130:  * of pa. However, it is advisable to have pa page aligned since otherwise,
                    131:  * we might have several mappings for a given chunk of the IO page.
                    132:  */
                    133: vaddr_t
                    134: mapiodev(paddr_t addr, int _size)
                    135: {
                    136:        vaddr_t va, iova, off;
                    137:        paddr_t pa, epa;
                    138:        psize_t size;
                    139:        int s, error;
                    140:
                    141:        /* sanity checks */
                    142:        if (_size <= 0)
                    143:                return NULL;
                    144:        size = (psize_t)_size;
                    145:        epa = addr + size;
                    146:        if (epa < addr && epa != 0)
                    147:                return NULL;
                    148:
                    149:        /* check for 1:1 mapping */
                    150:        if (addr >= bs_obio_start) {
                    151:                if (bs_obio_end == 0 || epa <= bs_obio_end)
                    152:                        return ((vaddr_t)addr);
                    153:                else if (addr <= bs_obio_end)
                    154:                        /* accross obio and non-obio, not supported */
                    155:                        return NULL;
                    156:        }
                    157:
                    158:        pa = trunc_page(addr);
                    159:        off = addr & PGOFSET;
                    160:        size = round_page(off + size);
                    161:
                    162:        s = splhigh();
                    163:        error = extent_alloc_region(bs_extent, atop(pa), atop(size),
                    164:            EX_MALLOCOK | (cold ? 0 : EX_WAITSPACE));
                    165:        splx(s);
                    166:
                    167:        if (error != 0)
                    168:                return NULL;
                    169:
                    170:        va = uvm_km_valloc(kernel_map, size);
                    171:        if (va == 0) {
                    172:                extent_free(bs_extent, atop(pa), atop(size),
                    173:                    EX_MALLOCOK | (cold ? 0 : EX_WAITSPACE));
                    174:                return NULL;
                    175:        }
                    176:
                    177:        iova = va + off;
                    178:        while (size != 0) {
                    179:                pmap_enter(pmap_kernel(), va, pa, UVM_PROT_RW,
                    180:                    UVM_PROT_RW | PMAP_WIRED);
                    181:                size -= PAGE_SIZE;
                    182:                va += PAGE_SIZE;
                    183:                pa += PAGE_SIZE;
                    184:        }
                    185:        pmap_update(pmap_kernel());
                    186:
                    187:        return (iova);
                    188: }
                    189:
                    190: /*
                    191:  * Free up the mapping in iomap.
                    192:  */
                    193: void
                    194: unmapiodev(vaddr_t va, int _size)
                    195: {
                    196:        vaddr_t eva, kva, off;
                    197:        vsize_t size;
                    198:        paddr_t pa;
                    199:        int s, error;
                    200:
                    201:        /* sanity checks */
                    202:        if (_size <= 0)
                    203:                return;
                    204:        size = (vsize_t)_size;
                    205:        eva = va + size;
                    206:        if (eva < va && eva != 0)
                    207:                return;
                    208:
                    209:        /* check for 1:1 mapping */
                    210:        if (va >= bs_obio_start) {
                    211:                if (bs_obio_end == 0 || eva <= bs_obio_end)
                    212:                        return;
                    213:                else if (va <= bs_obio_end)
                    214:                        /* accross obio and non-obio, not supported */
                    215:                        return;
                    216:        }
                    217:
                    218:        off = va & PGOFSET;
                    219:        kva = trunc_page(va);
                    220:        size = round_page(off + size);
                    221:
                    222:        if (pmap_extract(pmap_kernel(), kva, &pa) == FALSE)
                    223:                panic("unmapiodev(%p,%p)", kva, size);
                    224:
                    225:        pmap_remove(pmap_kernel(), kva, kva + size);
                    226:        pmap_update(pmap_kernel());
                    227:        uvm_km_free(kernel_map, kva, size);
                    228:
                    229:        s = splhigh();
                    230:        error = extent_free(bs_extent, atop(pa), atop(size),
                    231:            EX_MALLOCOK | (cold ? 0 : EX_WAITSPACE));
                    232: #ifdef DIAGNOSTIC
                    233:        if (error != 0)
                    234:                printf("unmapiodev(%p pa %p, %p): extent_free failed\n",
                    235:                    kva, pa, size);
                    236: #endif
                    237:        splx(s);
                    238: }
                    239:
                    240: /*
                    241:  * Configuration glue
                    242:  */
                    243:
                    244: struct cfattach mainbus_ca = {
                    245:        sizeof(struct device), mainbus_match, mainbus_attach
                    246: };
                    247:
                    248: struct cfdriver mainbus_cd = {
                    249:        NULL, "mainbus", DV_DULL
                    250: };
                    251:
                    252: int
                    253: mainbus_match(struct device *parent, void *cf, void *args)
                    254: {
                    255:        return (1);
                    256: }
                    257:
                    258: int
                    259: mainbus_print(void *args, const char *bus)
                    260: {
                    261:        struct confargs *ca = args;
                    262:
                    263:        if (ca->ca_paddr != -1)
                    264:                printf(" addr 0x%x", ca->ca_paddr);
                    265:        return (UNCONF);
                    266: }
                    267:
                    268: int
                    269: mainbus_scan(struct device *parent, void *child, void *args)
                    270: {
                    271:        struct cfdata *cf = child;
                    272:        struct confargs oca;
                    273:
                    274:        bzero(&oca, sizeof oca);
                    275:        oca.ca_iot = &mainbus_bustag;
                    276:        oca.ca_dmat = 0;        /* XXX no need for a meaningful value yet */
                    277:        oca.ca_bustype = BUS_MAIN;
                    278:        oca.ca_paddr = cf->cf_loc[0];
                    279:        oca.ca_ipl = -1;
                    280:        oca.ca_name = cf->cf_driver->cd_name;
                    281:        if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0)
                    282:                return (0);
                    283:        config_attach(parent, cf, &oca, mainbus_print);
                    284:        return (1);
                    285: }
                    286:
                    287: void
                    288: mainbus_attach(struct device *parent, struct device *self, void *args)
                    289: {
                    290:        extern char cpu_model[];
                    291:
                    292:        printf(": %s\n", cpu_model);
                    293:
                    294:        /*
                    295:         * Display cpu/mmu details for the main processor.
                    296:         */
                    297:        cpu_configuration_print(1);
                    298:
                    299:        /*
                    300:         * Initialize an extent to keep track of I/O mappings.
                    301:         */
                    302: #ifdef M88100
                    303:        if (CPU_IS88100) {
                    304:                bs_obio_start = BATC8_VA;       /* hardwired BATC */
                    305:                bs_obio_end = 0;
                    306:        }
                    307: #endif
                    308: #ifdef MVME197
                    309:        if (CPU_IS88110) {
                    310:                bs_obio_start = OBIO197_START;
                    311:                bs_obio_end = OBIO197_START + OBIO197_SIZE;
                    312:        }
                    313: #endif
                    314:        bs_extent = extent_create("bus_space", atop(physmem),
                    315:            1 + atop(0U - PAGE_SIZE), M_DEVBUF, NULL, 0, EX_NOWAIT);
                    316:        if (bs_extent == NULL)
                    317:                panic("unable to allocate bus_space extent");
                    318:
                    319:        (void)config_search(mainbus_scan, self, args);
                    320: }

CVSweb