int bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { int error; struct extent *ex; /* * Pick the appropriate extent map. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; if (flags & BUS_SPACE_MAP_LINEAR) return (EINVAL); } else if (t == X86_BUS_SPACE_MEM) ex = iomem_ex; else panic("bus_space_map: bad bus space tag"); /* * Before we go any further, let's make sure that this * region is available. */ error = extent_alloc_region(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); if (error) return (error); /* * For I/O space, that's all she wrote. */ if (t == X86_BUS_SPACE_IO) { *bshp = bpa; return (0); } if (bpa >= IOM_BEGIN && (bpa + size) <= IOM_END) { *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa); return(0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ error = x86_mem_add_mapping(bpa, size, flags, bshp); if (error) { if (extent_free(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_map: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_map: can't free region\n"); } } return (error); }
int _bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { /* * For I/O space, just fill in the handle. */ if (t == X86_BUS_SPACE_IO) { *bshp = bpa; return (0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ return (x86_mem_add_mapping(bpa, size, flags, bshp)); }
/* * can't use bus_space_xxx as we don't have a bus handle ... */ void ioapic_attach(struct device *parent, struct device *self, void *aux) { struct ioapic_softc *sc = (struct ioapic_softc *)self; struct apic_attach_args *aaa = (struct apic_attach_args *) aux; int apic_id; bus_space_handle_t bh; u_int32_t ver_sz; int i; sc->sc_flags = aaa->flags; sc->sc_apicid = aaa->apic_id; printf(" apid %d", aaa->apic_id); if (ioapic_find(aaa->apic_id) != NULL) { printf(", duplicate apic id (ignored)\n"); return; } ioapic_add(sc); printf(" pa 0x%lx", aaa->apic_address); if (x86_mem_add_mapping(aaa->apic_address, PAGE_SIZE, 0, &bh) != 0) { printf(", map failed\n"); return; } sc->sc_reg = (volatile u_int32_t *)(bh + IOAPIC_REG); sc->sc_data = (volatile u_int32_t *)(bh + IOAPIC_DATA); sc->sc_pic.pic_type = PIC_IOAPIC; mtx_init(&sc->sc_pic.pic_mutex, IPL_NONE); sc->sc_pic.pic_hwmask = ioapic_hwmask; sc->sc_pic.pic_hwunmask = ioapic_hwunmask; sc->sc_pic.pic_addroute = ioapic_addroute; sc->sc_pic.pic_delroute = ioapic_delroute; sc->sc_pic.pic_edge_stubs = ioapic_edge_stubs; sc->sc_pic.pic_level_stubs = ioapic_level_stubs; ver_sz = ioapic_read(sc, IOAPIC_VER); sc->sc_apic_vers = (ver_sz & IOAPIC_VER_MASK) >> IOAPIC_VER_SHIFT; sc->sc_apic_sz = (ver_sz & IOAPIC_MAX_MASK) >> IOAPIC_MAX_SHIFT; sc->sc_apic_sz++; if (aaa->apic_vecbase != -1) sc->sc_apic_vecbase = aaa->apic_vecbase; else { /* * XXX this assumes ordering of ioapics in the table. * Only needed for broken BIOS workaround (see mpbios.c) */ sc->sc_apic_vecbase = ioapic_vecbase; ioapic_vecbase += sc->sc_apic_sz; } if (mp_verbose) { printf(", %s mode", aaa->flags & IOAPIC_PICMODE ? "PIC" : "virtual wire"); } printf(", version %x, %d pins\n", sc->sc_apic_vers, sc->sc_apic_sz); apic_id = (ioapic_read(sc, IOAPIC_ID) & IOAPIC_ID_MASK) >> IOAPIC_ID_SHIFT; sc->sc_pins = malloc(sizeof(struct ioapic_pin) * sc->sc_apic_sz, M_DEVBUF, M_WAITOK); for (i=0; i<sc->sc_apic_sz; i++) { sc->sc_pins[i].ip_next = NULL; sc->sc_pins[i].ip_map = NULL; sc->sc_pins[i].ip_vector = 0; sc->sc_pins[i].ip_type = IST_NONE; } /* * In case the APIC is not initialized to the correct ID * do it now. * Maybe we should record the original ID for interrupt * mapping later ... */ if (apic_id != sc->sc_apicid) { printf("%s: misconfigured as apic %d", sc->sc_pic.pic_dev.dv_xname, apic_id); ioapic_set_id(sc); } #if 0 /* output of this was boring. */ if (mp_verbose) for (i=0; i<sc->sc_apic_sz; i++) ioapic_print_redir(sc, "boot", i); #endif }
int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, bus_addr_t *bpap, bus_space_handle_t *bshp) { struct extent *ex; u_long bpa; int error; /* * Pick the appropriate extent map. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; } else if (t == X86_BUS_SPACE_MEM) ex = iomem_ex; else panic("bus_space_alloc: bad bus space tag"); /* * Sanity check the allocation against the extent's boundaries. */ if (rstart < ex->ex_start || rend > ex->ex_end) panic("bus_space_alloc: bad region start/end"); /* * Do the requested allocation. */ error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 0, boundary, EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0), &bpa); if (error) return (error); /* * For I/O space, that's all she wrote. */ if (t == X86_BUS_SPACE_IO) { *bshp = *bpap = bpa; return (0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ error = x86_mem_add_mapping(bpa, size, flags, bshp); if (error) { if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_alloc: can't free region\n"); } } *bpap = bpa; return (error); }