[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     ! 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