int __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags, struct mips_bus_space_translation *mbst) { bus_addr_t end = addr + (len - 1); #if CHIP_ALIGN_STRIDE != 0 int linear = flags & BUS_SPACE_MAP_LINEAR; /* * Can't map xxx space linearly. */ if (linear) return (EOPNOTSUPP); #endif #ifdef CHIP_W1_BUS_START if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v)) return (__BS(get_window)(v, 0, mbst)); #endif #ifdef CHIP_W2_BUS_START if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v)) return (__BS(get_window)(v, 1, mbst)); #endif #ifdef CHIP_W3_BUS_START if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v)) return (__BS(get_window)(v, 2, mbst)); #endif #ifdef EXTENT_DEBUG printf("\n"); #ifdef CHIP_W1_BUS_START printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v)); #endif #ifdef CHIP_W2_BUS_START printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif #ifdef CHIP_W3_BUS_START printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); #endif #endif /* EXTENT_DEBUG */ /* No translation. */ return (EINVAL); }
int __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst) { switch (window) { #ifdef CHIP_W1_BUS_START case 0: mbst->mbst_bus_start = CHIP_W1_BUS_START(v); mbst->mbst_bus_end = CHIP_W1_BUS_END(v); mbst->mbst_sys_start = CHIP_W1_SYS_START(v); mbst->mbst_sys_end = CHIP_W1_SYS_END(v); mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; mbst->mbst_flags = 0; break; #endif #ifdef CHIP_W2_BUS_START case 1: mbst->mbst_bus_start = CHIP_W2_BUS_START(v); mbst->mbst_bus_end = CHIP_W2_BUS_END(v); mbst->mbst_sys_start = CHIP_W2_SYS_START(v); mbst->mbst_sys_end = CHIP_W2_SYS_END(v); mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; mbst->mbst_flags = 0; break; #endif #ifdef CHIP_W3_BUS_START case 2: mbst->mbst_bus_start = CHIP_W3_BUS_START(v); mbst->mbst_bus_end = CHIP_W3_BUS_END(v); mbst->mbst_sys_start = CHIP_W3_SYS_START(v); mbst->mbst_sys_end = CHIP_W3_SYS_END(v); mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; mbst->mbst_flags = 0; break; #endif default: panic(__S(__BS(get_window)) ": invalid window %d", window); } return (0); }
void __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) { #ifdef CHIP_EXTENT bus_addr_t addr; int error; if (acct == 0) return; #ifdef EXTENT_DEBUG printf("xxx: freeing handle 0x%lx for 0x%lx\n", h, size); #endif if (h >= MIPS_KSEG0_START && h < MIPS_KSEG1_START) h = MIPS_KSEG0_TO_PHYS(h); else h = MIPS_KSEG1_TO_PHYS(h); #ifdef CHIP_W1_BUS_START if (h >= CHIP_W1_SYS_START(v) && h <= CHIP_W1_SYS_END(v)) { addr = CHIP_W1_BUS_START(v) + (h - CHIP_W1_SYS_START(v)); } else #endif #ifdef CHIP_W2_BUS_START if (h >= CHIP_W2_SYS_START(v) && h <= CHIP_W2_SYS_END(v)) { addr = CHIP_W2_BUS_START(v) + (h - CHIP_W2_SYS_START(v)); } else #endif #ifdef CHIP_W3_BUS_START if (h >= CHIP_W3_SYS_START(v) && h <= CHIP_W3_SYS_END(v)) { addr = CHIP_W3_BUS_START(v) + (h - CHIP_W3_SYS_START(v)); } else #endif { printf("\n"); #ifdef CHIP_W1_BUS_START printf("%s: sys window[1]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v), (u_long)CHIP_W1_SYS_END(v)); #endif #ifdef CHIP_W2_BUS_START printf("%s: sys window[2]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v), (u_long)CHIP_W2_SYS_END(v)); #endif #ifdef CHIP_W3_BUS_START printf("%s: sys window[3]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W3_SYS_START(v), (u_long)CHIP_W3_SYS_END(v)); #endif panic("%s: don't know how to unmap %lx", __S(__BS(unmap)), h); } #ifdef EXTENT_DEBUG printf("xxx: freeing 0x%lx to 0x%lx\n", addr, addr + size - 1); #endif error = extent_free(CHIP_EXTENT(v), addr, size, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); if (error) { printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", __S(__BS(unmap)), addr, addr + size - 1, error); #ifdef EXTENT_DEBUG extent_print(CHIP_EXTENT(v)); #endif } #endif /* CHIP_EXTENT */ }
void __BS(init)(bus_space_tag_t t, void *v) { #ifdef CHIP_EXTENT struct extent *ex; #endif /* * Initialize the bus space tag. */ /* cookie */ t->bs_cookie = v; /* mapping/unmapping */ t->bs_map = __BS(map); t->bs_unmap = __BS(unmap); t->bs_subregion = __BS(subregion); t->bs_translate = __BS(translate); t->bs_get_window = __BS(get_window); /* allocation/deallocation */ t->bs_alloc = __BS(alloc); t->bs_free = __BS(free); /* get kernel virtual address */ t->bs_vaddr = __BS(vaddr); /* mmap for user */ t->bs_mmap = __BS(mmap); /* barrier */ t->bs_barrier = __BS(barrier); /* read (single) */ t->bs_r_1 = __BS(read_1); t->bs_r_2 = __BS(read_2); t->bs_r_4 = __BS(read_4); t->bs_r_8 = __BS(read_8); /* read multiple */ t->bs_rm_1 = __BS(read_multi_1); t->bs_rm_2 = __BS(read_multi_2); t->bs_rm_4 = __BS(read_multi_4); t->bs_rm_8 = __BS(read_multi_8); /* read region */ t->bs_rr_1 = __BS(read_region_1); t->bs_rr_2 = __BS(read_region_2); t->bs_rr_4 = __BS(read_region_4); t->bs_rr_8 = __BS(read_region_8); /* write (single) */ t->bs_w_1 = __BS(write_1); t->bs_w_2 = __BS(write_2); t->bs_w_4 = __BS(write_4); t->bs_w_8 = __BS(write_8); /* write multiple */ t->bs_wm_1 = __BS(write_multi_1); t->bs_wm_2 = __BS(write_multi_2); t->bs_wm_4 = __BS(write_multi_4); t->bs_wm_8 = __BS(write_multi_8); /* write region */ t->bs_wr_1 = __BS(write_region_1); t->bs_wr_2 = __BS(write_region_2); t->bs_wr_4 = __BS(write_region_4); t->bs_wr_8 = __BS(write_region_8); /* set multiple */ t->bs_sm_1 = __BS(set_multi_1); t->bs_sm_2 = __BS(set_multi_2); t->bs_sm_4 = __BS(set_multi_4); t->bs_sm_8 = __BS(set_multi_8); /* set region */ t->bs_sr_1 = __BS(set_region_1); t->bs_sr_2 = __BS(set_region_2); t->bs_sr_4 = __BS(set_region_4); t->bs_sr_8 = __BS(set_region_8); /* copy */ t->bs_c_1 = __BS(copy_region_1); t->bs_c_2 = __BS(copy_region_2); t->bs_c_4 = __BS(copy_region_4); t->bs_c_8 = __BS(copy_region_8); #ifdef CHIP_NEED_STREAM /* read (single), stream */ t->bs_rs_1 = __BS(read_stream_1); t->bs_rs_2 = __BS(read_stream_2); t->bs_rs_4 = __BS(read_stream_4); t->bs_rs_8 = __BS(read_stream_8); /* read multiple, stream */ t->bs_rms_1 = __BS(read_multi_stream_1); t->bs_rms_2 = __BS(read_multi_stream_2); t->bs_rms_4 = __BS(read_multi_stream_4); t->bs_rms_8 = __BS(read_multi_stream_8); /* read region, stream */ t->bs_rrs_1 = __BS(read_region_stream_1); t->bs_rrs_2 = __BS(read_region_stream_2); t->bs_rrs_4 = __BS(read_region_stream_4); t->bs_rrs_8 = __BS(read_region_stream_8); /* write (single), stream */ t->bs_ws_1 = __BS(write_stream_1); t->bs_ws_2 = __BS(write_stream_2); t->bs_ws_4 = __BS(write_stream_4); t->bs_ws_8 = __BS(write_stream_8); /* write multiple, stream */ t->bs_wms_1 = __BS(write_multi_stream_1); t->bs_wms_2 = __BS(write_multi_stream_2); t->bs_wms_4 = __BS(write_multi_stream_4); t->bs_wms_8 = __BS(write_multi_stream_8); /* write region, stream */ t->bs_wrs_1 = __BS(write_region_stream_1); t->bs_wrs_2 = __BS(write_region_stream_2); t->bs_wrs_4 = __BS(write_region_stream_4); t->bs_wrs_8 = __BS(write_region_stream_8); #else /* CHIP_NEED_STREAM */ /* read (single), stream */ t->bs_rs_1 = __BS(read_1); t->bs_rs_2 = __BS(read_2); t->bs_rs_4 = __BS(read_4); t->bs_rs_8 = __BS(read_8); /* read multiple, stream */ t->bs_rms_1 = __BS(read_multi_1); t->bs_rms_2 = __BS(read_multi_2); t->bs_rms_4 = __BS(read_multi_4); t->bs_rms_8 = __BS(read_multi_8); /* read region, stream */ t->bs_rrs_1 = __BS(read_region_1); t->bs_rrs_2 = __BS(read_region_2); t->bs_rrs_4 = __BS(read_region_4); t->bs_rrs_8 = __BS(read_region_8); /* write (single), stream */ t->bs_ws_1 = __BS(write_1); t->bs_ws_2 = __BS(write_2); t->bs_ws_4 = __BS(write_4); t->bs_ws_8 = __BS(write_8); /* write multiple, stream */ t->bs_wms_1 = __BS(write_multi_1); t->bs_wms_2 = __BS(write_multi_2); t->bs_wms_4 = __BS(write_multi_4); t->bs_wms_8 = __BS(write_multi_8); /* write region, stream */ t->bs_wrs_1 = __BS(write_region_1); t->bs_wrs_2 = __BS(write_region_2); t->bs_wrs_4 = __BS(write_region_4); t->bs_wrs_8 = __BS(write_region_8); #endif /* CHIP_NEED_STREAM */ #ifdef CHIP_EXTENT /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ ex = extent_create(__S(__BS(bus)), 0x0UL, 0xffffffffUL, M_DEVBUF, (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); #ifdef CHIP_W1_BUS_START /* * The window may be disabled. We notice this by seeing * -1 as the bus base address. */ if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { #ifdef EXTENT_DEBUG printf("xxx: this space is disabled\n"); #endif return; } #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%x to 0x%x\n", CHIP_W1_BUS_START(v), CHIP_W1_BUS_END(v)); #endif extent_free(ex, CHIP_W1_BUS_START(v), CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); #endif #ifdef CHIP_W2_BUS_START if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%lx to 0x%lx\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif extent_free(ex, CHIP_W2_BUS_START(v), CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif } #endif #ifdef CHIP_W3_BUS_START if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%lx to 0x%lx\n", (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); #endif extent_free(ex, CHIP_W3_BUS_START(v), CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif } #endif #ifdef EXTENT_DEBUG extent_print(ex); #endif CHIP_EXTENT(v) = ex; #endif /* CHIP_EXTENT */ }
static void __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) { #if !defined(_LP64) || defined(CHIP_EXTENT) bus_addr_t addr = 0; /* initialize to appease gcc */ #endif #ifndef _LP64 bool handle_is_km; /* determine if h is addr obtained from uvm_km_alloc */ handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h)); #ifdef __mips_n32 if (handle_is_km == true) handle_is_km = !MIPS_XKPHYS_P(h); #endif if (handle_is_km == true) { paddr_t pa; vaddr_t va = (vaddr_t)trunc_page(h); vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size); int s; s = splhigh(); if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false) panic("%s: pmap_extract failed", __func__); addr = (bus_addr_t)pa; #if 0 printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n", __func__, __LINE__, addr, sz); #endif /* sanity check: this is why we couldn't map w/ kseg[0,1] */ KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0); pmap_kremove(va, sz); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY); splx(s); } #endif /* _LP64 */ #ifdef CHIP_EXTENT if (acct == 0) return; #ifdef EXTENT_DEBUG printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n", __S(__BS(unmap)), h, size); #endif #ifdef _LP64 KASSERT(MIPS_XKPHYS_P(h)); addr = MIPS_XKPHYS_TO_PHYS(h); #else if (handle_is_km == false) { if (MIPS_KSEG0_P(h)) addr = MIPS_KSEG0_TO_PHYS(h); #ifdef __mips_n32 else if (MIPS_XKPHYS_P(h)) addr = MIPS_XKPHYS_TO_PHYS(h); #endif else addr = MIPS_KSEG1_TO_PHYS(h); } #endif #ifdef CHIP_W1_BUS_START if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) { addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v)); } else #endif #ifdef CHIP_W2_BUS_START if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) { addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v)); } else #endif #ifdef CHIP_W3_BUS_START if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) { addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v)); } else #endif { printf("\n"); #ifdef CHIP_W1_BUS_START printf("%s: sys window[1]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W1_SYS_START(v), (u_long)CHIP_W1_SYS_END(v)); #endif #ifdef CHIP_W2_BUS_START printf("%s: sys window[2]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W2_SYS_START(v), (u_long)CHIP_W2_SYS_END(v)); #endif #ifdef CHIP_W3_BUS_START printf("%s: sys window[3]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v), (u_long)CHIP_W3_SYS_END(v)); #endif panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h); } #ifdef EXTENT_DEBUG printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", __S(__BS(unmap)), addr, addr + size - 1); #endif int error = extent_free(CHIP_EXTENT(v), addr, size, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); if (error) { printf("%s: WARNING: could not unmap" " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n", __S(__BS(unmap)), addr, addr + size - 1, error); #ifdef EXTENT_DEBUG extent_print(CHIP_EXTENT(v)); #endif } #endif /* CHIP_EXTENT */ #if !defined(_LP64) || defined(CHIP_EXTENT) __USE(addr); #endif }