/* $NetBSD: bus_space_large.c,v 1.9 2023/12/20 06:36:02 thorpej Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace * Simulation Facility, NASA Ames Research Center. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``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 FOUNDATION OR CONTRIBUTORS * 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. */ /* * For large sparse bus space * (e.g. NEC RISCstation 2250 PCI memory space: 432MB) * * This bus_space uses either wired TLB or normal KSEG2 mapping * for each bus space region. * * Wired TLB will be used on the following cases: * - If requested region is already mapped by wired TLBs. * This is needed for some critical resources which are used * on kernel early stage (e.g. console device resources) * - If requested region size >= ARC_THRESHOLD_TO_USE_WIRED_TLB, * and enough wired TLBs are still free. * In this case, the size of wired TLBs becomes always * MIPS3_WIRED_SIZE (i.e. 16MB). (See wired_map_machdep.c for detail.) */ #include __KERNEL_RCSID(0, "$NetBSD: bus_space_large.c,v 1.9 2023/12/20 06:36:02 thorpej Exp $"); #include #include #include #include #include static int arc_large_bus_space_compose_handle(bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *); static int arc_large_bus_space_dispose_handle(bus_space_tag_t, bus_space_handle_t, bus_size_t); static int arc_large_bus_space_paddr(bus_space_tag_t, bus_space_handle_t, paddr_t *); void arc_large_bus_space_init(bus_space_tag_t bst, const char *name, paddr_t paddr, bus_addr_t start, bus_size_t size) { arc_sparse_bus_space_init(bst, name, paddr, start, size); bst->bs_compose_handle = arc_large_bus_space_compose_handle; bst->bs_dispose_handle = arc_large_bus_space_dispose_handle; bst->bs_paddr = arc_large_bus_space_paddr; } static int arc_large_bus_space_compose_handle(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) { paddr_t pa; vaddr_t va; pa = bst->bs_pbase + (addr - bst->bs_start); /* * Check whether the physical address is already wired mapped * or not. If not mapped but requested region is large enough, * try to use wired TLB. */ if ((va = arc_contiguously_wired_mapped(pa, size)) != 0 || (/* requested region is large enough? */ size >= ARC_THRESHOLD_TO_USE_WIRED_TLB && /* enough wired TLBs are still available? */ (va = arc_map_wired(pa, size)) != 0)) { #ifdef DIAGNOSTIC /* * If wired TLB is used, * we will not make this bus_space region cacheable, * since other bus_space might share this wired TLB. */ if (flags & BUS_SPACE_MAP_CACHEABLE) printf("arc_large_bus_space_compose_handle: " "ignore cacheable 0x%llx..0x%llx\n", pa, pa + size - 1); #endif *bshp = va; return 0; } return arc_sparse_bus_space_compose_handle(bst, addr, size, flags, bshp); } static int arc_large_bus_space_dispose_handle(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size) { paddr_t pa; /* * We never free already wired TLB entries, * since the TLBs might be used for other bus_space region. */ if (arc_wired_map_extract(bsh, &pa)) return 0; return arc_sparse_bus_space_dispose_handle(bst, bsh, size); } static int arc_large_bus_space_paddr(bus_space_tag_t bst, bus_space_handle_t bsh, paddr_t *pap) { if (arc_wired_map_extract(bsh, pap)) return 0; return arc_sparse_bus_space_paddr(bst, bsh, pap); }