1*e12dfaa1Skettenis /* $OpenBSD: bus_space.c,v 1.27 2022/06/29 07:44:10 kettenis Exp $ */ 2f5df1827Smickey /* $NetBSD: bus_space.c,v 1.2 2003/03/14 18:47:53 christos Exp $ */ 3f5df1827Smickey 4f5df1827Smickey /*- 5f5df1827Smickey * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 6f5df1827Smickey * All rights reserved. 7f5df1827Smickey * 8f5df1827Smickey * This code is derived from software contributed to The NetBSD Foundation 9f5df1827Smickey * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 10f5df1827Smickey * Simulation Facility, NASA Ames Research Center. 11f5df1827Smickey * 12f5df1827Smickey * Redistribution and use in source and binary forms, with or without 13f5df1827Smickey * modification, are permitted provided that the following conditions 14f5df1827Smickey * are met: 15f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 16f5df1827Smickey * notice, this list of conditions and the following disclaimer. 17f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 18f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 19f5df1827Smickey * documentation and/or other materials provided with the distribution. 20f5df1827Smickey * 21f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22f5df1827Smickey * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23f5df1827Smickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24f5df1827Smickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25f5df1827Smickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26f5df1827Smickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27f5df1827Smickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28f5df1827Smickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29f5df1827Smickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30f5df1827Smickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31f5df1827Smickey * POSSIBILITY OF SUCH DAMAGE. 32f5df1827Smickey */ 33f5df1827Smickey 34f5df1827Smickey #include <sys/param.h> 35f5df1827Smickey #include <sys/systm.h> 36f5df1827Smickey #include <sys/malloc.h> 37f5df1827Smickey #include <sys/extent.h> 38f5df1827Smickey 39f5df1827Smickey #include <uvm/uvm_extern.h> 40f5df1827Smickey 41f5df1827Smickey #include <machine/bus.h> 42f5df1827Smickey 43f5df1827Smickey #include <dev/isa/isareg.h> 44f5df1827Smickey #include <machine/isa_machdep.h> 45f5df1827Smickey 46*e12dfaa1Skettenis extern int pmap_initialized; 47*e12dfaa1Skettenis 48f5df1827Smickey /* 49f5df1827Smickey * Extent maps to manage I/O and memory space. Allocate 5048cd2e59Smikeb * storage for 16 regions in each, initially. Later, ioport_malloc_safe 51f5df1827Smickey * will indicate that it's safe to use malloc() to dynamically allocate 52f5df1827Smickey * region descriptors. 53f5df1827Smickey * 54f5df1827Smickey * N.B. At least two regions are _always_ allocated from the iomem 55f5df1827Smickey * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 56f5df1827Smickey * 57f5df1827Smickey * The extent maps are not static! Machine-dependent ISA and EISA 58f5df1827Smickey * routines need access to them for bus address space allocation. 59f5df1827Smickey */ 6048cd2e59Smikeb static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)]; 6148cd2e59Smikeb static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)]; 62f5df1827Smickey struct extent *ioport_ex; 63f5df1827Smickey struct extent *iomem_ex; 64f5df1827Smickey static int ioport_malloc_safe; 65f5df1827Smickey 66f5df1827Smickey int x86_mem_add_mapping(bus_addr_t, bus_size_t, 67f5df1827Smickey int, bus_space_handle_t *); 68f5df1827Smickey 6993c7b57cSdlg u_int8_t x86_bus_space_io_read_1(bus_space_handle_t, bus_size_t); 7093c7b57cSdlg u_int16_t x86_bus_space_io_read_2(bus_space_handle_t, bus_size_t); 7193c7b57cSdlg u_int32_t x86_bus_space_io_read_4(bus_space_handle_t, bus_size_t); 7293c7b57cSdlg u_int64_t x86_bus_space_io_read_8(bus_space_handle_t, bus_size_t); 7393c7b57cSdlg 7493c7b57cSdlg void x86_bus_space_io_read_multi_1(bus_space_handle_t, bus_size_t, 7593c7b57cSdlg u_int8_t *, bus_size_t); 7693c7b57cSdlg void x86_bus_space_io_read_multi_2(bus_space_handle_t, bus_size_t, 7793c7b57cSdlg u_int16_t *, bus_size_t); 7893c7b57cSdlg void x86_bus_space_io_read_multi_4(bus_space_handle_t, bus_size_t, 7993c7b57cSdlg u_int32_t *, bus_size_t); 8093c7b57cSdlg void x86_bus_space_io_read_multi_8(bus_space_handle_t, bus_size_t, 8193c7b57cSdlg u_int64_t *, bus_size_t); 8293c7b57cSdlg 8393c7b57cSdlg void x86_bus_space_io_read_region_1(bus_space_handle_t, bus_size_t, 8493c7b57cSdlg u_int8_t *, bus_size_t); 8593c7b57cSdlg void x86_bus_space_io_read_region_2(bus_space_handle_t, bus_size_t, 8693c7b57cSdlg u_int16_t *, bus_size_t); 8793c7b57cSdlg void x86_bus_space_io_read_region_4(bus_space_handle_t, bus_size_t, 8893c7b57cSdlg u_int32_t *, bus_size_t); 8993c7b57cSdlg void x86_bus_space_io_read_region_8(bus_space_handle_t, bus_size_t, 9093c7b57cSdlg u_int64_t *, bus_size_t); 9193c7b57cSdlg 9293c7b57cSdlg void x86_bus_space_io_write_1(bus_space_handle_t, bus_size_t, 9393c7b57cSdlg u_int8_t); 9493c7b57cSdlg void x86_bus_space_io_write_2(bus_space_handle_t, bus_size_t, 9593c7b57cSdlg u_int16_t); 9693c7b57cSdlg void x86_bus_space_io_write_4(bus_space_handle_t, bus_size_t, 9793c7b57cSdlg u_int32_t); 9893c7b57cSdlg void x86_bus_space_io_write_8(bus_space_handle_t, bus_size_t, 9993c7b57cSdlg u_int64_t); 10093c7b57cSdlg 10193c7b57cSdlg void x86_bus_space_io_write_multi_1(bus_space_handle_t, 10293c7b57cSdlg bus_size_t, const u_int8_t *, bus_size_t); 10393c7b57cSdlg void x86_bus_space_io_write_multi_2(bus_space_handle_t, 10493c7b57cSdlg bus_size_t, const u_int16_t *, bus_size_t); 10593c7b57cSdlg void x86_bus_space_io_write_multi_4(bus_space_handle_t, 10693c7b57cSdlg bus_size_t, const u_int32_t *, bus_size_t); 10793c7b57cSdlg void x86_bus_space_io_write_multi_8(bus_space_handle_t, 10893c7b57cSdlg bus_size_t, const u_int64_t *, bus_size_t); 10993c7b57cSdlg 11093c7b57cSdlg void x86_bus_space_io_write_region_1(bus_space_handle_t, 11193c7b57cSdlg bus_size_t, const u_int8_t *, bus_size_t); 11293c7b57cSdlg void x86_bus_space_io_write_region_2(bus_space_handle_t, 11393c7b57cSdlg bus_size_t, const u_int16_t *, bus_size_t); 11493c7b57cSdlg void x86_bus_space_io_write_region_4(bus_space_handle_t, 11593c7b57cSdlg bus_size_t, const u_int32_t *, bus_size_t); 11693c7b57cSdlg void x86_bus_space_io_write_region_8(bus_space_handle_t, 11793c7b57cSdlg bus_size_t, const u_int64_t *, bus_size_t); 11893c7b57cSdlg 11993c7b57cSdlg void x86_bus_space_io_set_multi_1(bus_space_handle_t, bus_size_t, 12093c7b57cSdlg u_int8_t, size_t); 12193c7b57cSdlg void x86_bus_space_io_set_multi_2(bus_space_handle_t, bus_size_t, 12293c7b57cSdlg u_int16_t, size_t); 12393c7b57cSdlg void x86_bus_space_io_set_multi_4(bus_space_handle_t, bus_size_t, 12493c7b57cSdlg u_int32_t, size_t); 12593c7b57cSdlg void x86_bus_space_io_set_multi_8(bus_space_handle_t, bus_size_t, 12693c7b57cSdlg u_int64_t, size_t); 12793c7b57cSdlg 12893c7b57cSdlg void x86_bus_space_io_set_region_1(bus_space_handle_t, bus_size_t, 12993c7b57cSdlg u_int8_t, size_t); 13093c7b57cSdlg void x86_bus_space_io_set_region_2(bus_space_handle_t, bus_size_t, 13193c7b57cSdlg u_int16_t, size_t); 13293c7b57cSdlg void x86_bus_space_io_set_region_4(bus_space_handle_t, bus_size_t, 13393c7b57cSdlg u_int32_t, size_t); 13493c7b57cSdlg void x86_bus_space_io_set_region_8(bus_space_handle_t, bus_size_t, 13593c7b57cSdlg u_int64_t, size_t); 13693c7b57cSdlg 13793c7b57cSdlg void x86_bus_space_io_copy_1(bus_space_handle_t, bus_size_t, 13893c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 13993c7b57cSdlg void x86_bus_space_io_copy_2(bus_space_handle_t, bus_size_t, 14093c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 14193c7b57cSdlg void x86_bus_space_io_copy_4(bus_space_handle_t, bus_size_t, 14293c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 14393c7b57cSdlg void x86_bus_space_io_copy_8(bus_space_handle_t, bus_size_t, 14493c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 14593c7b57cSdlg 14693c7b57cSdlg void * x86_bus_space_io_vaddr(bus_space_handle_t); 14793c7b57cSdlg paddr_t x86_bus_space_io_mmap(bus_addr_t, off_t, int, int); 14893c7b57cSdlg 14993c7b57cSdlg const struct x86_bus_space_ops x86_bus_space_io_ops = { 15093c7b57cSdlg x86_bus_space_io_read_1, 15193c7b57cSdlg x86_bus_space_io_read_2, 15293c7b57cSdlg x86_bus_space_io_read_4, 15393c7b57cSdlg x86_bus_space_io_read_8, 15493c7b57cSdlg x86_bus_space_io_read_multi_1, 15593c7b57cSdlg x86_bus_space_io_read_multi_2, 15693c7b57cSdlg x86_bus_space_io_read_multi_4, 15793c7b57cSdlg x86_bus_space_io_read_multi_8, 15893c7b57cSdlg x86_bus_space_io_read_region_1, 15993c7b57cSdlg x86_bus_space_io_read_region_2, 16093c7b57cSdlg x86_bus_space_io_read_region_4, 16193c7b57cSdlg x86_bus_space_io_read_region_8, 16293c7b57cSdlg x86_bus_space_io_write_1, 16393c7b57cSdlg x86_bus_space_io_write_2, 16493c7b57cSdlg x86_bus_space_io_write_4, 16593c7b57cSdlg x86_bus_space_io_write_8, 16693c7b57cSdlg x86_bus_space_io_write_multi_1, 16793c7b57cSdlg x86_bus_space_io_write_multi_2, 16893c7b57cSdlg x86_bus_space_io_write_multi_4, 16993c7b57cSdlg x86_bus_space_io_write_multi_8, 17093c7b57cSdlg x86_bus_space_io_write_region_1, 17193c7b57cSdlg x86_bus_space_io_write_region_2, 17293c7b57cSdlg x86_bus_space_io_write_region_4, 17393c7b57cSdlg x86_bus_space_io_write_region_8, 17493c7b57cSdlg x86_bus_space_io_set_multi_1, 17593c7b57cSdlg x86_bus_space_io_set_multi_2, 17693c7b57cSdlg x86_bus_space_io_set_multi_4, 17793c7b57cSdlg x86_bus_space_io_set_multi_8, 17893c7b57cSdlg x86_bus_space_io_set_region_1, 17993c7b57cSdlg x86_bus_space_io_set_region_2, 18093c7b57cSdlg x86_bus_space_io_set_region_4, 18193c7b57cSdlg x86_bus_space_io_set_region_8, 18293c7b57cSdlg x86_bus_space_io_copy_1, 18393c7b57cSdlg x86_bus_space_io_copy_2, 18493c7b57cSdlg x86_bus_space_io_copy_4, 18593c7b57cSdlg x86_bus_space_io_copy_8, 18693c7b57cSdlg x86_bus_space_io_vaddr, 18793c7b57cSdlg x86_bus_space_io_mmap 18893c7b57cSdlg }; 18993c7b57cSdlg 19093c7b57cSdlg u_int8_t x86_bus_space_mem_read_1(bus_space_handle_t, bus_size_t); 19193c7b57cSdlg u_int16_t x86_bus_space_mem_read_2(bus_space_handle_t, bus_size_t); 19293c7b57cSdlg u_int32_t x86_bus_space_mem_read_4(bus_space_handle_t, bus_size_t); 19393c7b57cSdlg u_int64_t x86_bus_space_mem_read_8(bus_space_handle_t, bus_size_t); 19493c7b57cSdlg 19593c7b57cSdlg void x86_bus_space_mem_read_multi_1(bus_space_handle_t, bus_size_t, 19693c7b57cSdlg u_int8_t *, bus_size_t); 19793c7b57cSdlg void x86_bus_space_mem_read_multi_2(bus_space_handle_t, bus_size_t, 19893c7b57cSdlg u_int16_t *, bus_size_t); 19993c7b57cSdlg void x86_bus_space_mem_read_multi_4(bus_space_handle_t, bus_size_t, 20093c7b57cSdlg u_int32_t *, bus_size_t); 20193c7b57cSdlg void x86_bus_space_mem_read_multi_8(bus_space_handle_t, bus_size_t, 20293c7b57cSdlg u_int64_t *, bus_size_t); 20393c7b57cSdlg 20493c7b57cSdlg void x86_bus_space_mem_read_region_1(bus_space_handle_t, bus_size_t, 20593c7b57cSdlg u_int8_t *, bus_size_t); 20693c7b57cSdlg void x86_bus_space_mem_read_region_2(bus_space_handle_t, bus_size_t, 20793c7b57cSdlg u_int16_t *, bus_size_t); 20893c7b57cSdlg void x86_bus_space_mem_read_region_4(bus_space_handle_t, bus_size_t, 20993c7b57cSdlg u_int32_t *, bus_size_t); 21093c7b57cSdlg void x86_bus_space_mem_read_region_8(bus_space_handle_t, bus_size_t, 21193c7b57cSdlg u_int64_t *, bus_size_t); 21293c7b57cSdlg 21393c7b57cSdlg void x86_bus_space_mem_write_1(bus_space_handle_t, bus_size_t, 21493c7b57cSdlg u_int8_t); 21593c7b57cSdlg void x86_bus_space_mem_write_2(bus_space_handle_t, bus_size_t, 21693c7b57cSdlg u_int16_t); 21793c7b57cSdlg void x86_bus_space_mem_write_4(bus_space_handle_t, bus_size_t, 21893c7b57cSdlg u_int32_t); 21993c7b57cSdlg void x86_bus_space_mem_write_8(bus_space_handle_t, bus_size_t, 22093c7b57cSdlg u_int64_t); 22193c7b57cSdlg 22293c7b57cSdlg void x86_bus_space_mem_write_multi_1(bus_space_handle_t, 22393c7b57cSdlg bus_size_t, const u_int8_t *, bus_size_t); 22493c7b57cSdlg void x86_bus_space_mem_write_multi_2(bus_space_handle_t, 22593c7b57cSdlg bus_size_t, const u_int16_t *, bus_size_t); 22693c7b57cSdlg void x86_bus_space_mem_write_multi_4(bus_space_handle_t, 22793c7b57cSdlg bus_size_t, const u_int32_t *, bus_size_t); 22893c7b57cSdlg void x86_bus_space_mem_write_multi_8(bus_space_handle_t, 22993c7b57cSdlg bus_size_t, const u_int64_t *, bus_size_t); 23093c7b57cSdlg 23193c7b57cSdlg void x86_bus_space_mem_write_region_1(bus_space_handle_t, 23293c7b57cSdlg bus_size_t, const u_int8_t *, bus_size_t); 23393c7b57cSdlg void x86_bus_space_mem_write_region_2(bus_space_handle_t, 23493c7b57cSdlg bus_size_t, const u_int16_t *, bus_size_t); 23593c7b57cSdlg void x86_bus_space_mem_write_region_4(bus_space_handle_t, 23693c7b57cSdlg bus_size_t, const u_int32_t *, bus_size_t); 23793c7b57cSdlg void x86_bus_space_mem_write_region_8(bus_space_handle_t, 23893c7b57cSdlg bus_size_t, const u_int64_t *, bus_size_t); 23993c7b57cSdlg 24093c7b57cSdlg void x86_bus_space_mem_set_multi_1(bus_space_handle_t, bus_size_t, 24193c7b57cSdlg u_int8_t, size_t); 24293c7b57cSdlg void x86_bus_space_mem_set_multi_2(bus_space_handle_t, bus_size_t, 24393c7b57cSdlg u_int16_t, size_t); 24493c7b57cSdlg void x86_bus_space_mem_set_multi_4(bus_space_handle_t, bus_size_t, 24593c7b57cSdlg u_int32_t, size_t); 24693c7b57cSdlg void x86_bus_space_mem_set_multi_8(bus_space_handle_t, bus_size_t, 24793c7b57cSdlg u_int64_t, size_t); 24893c7b57cSdlg 24993c7b57cSdlg void x86_bus_space_mem_set_region_1(bus_space_handle_t, bus_size_t, 25093c7b57cSdlg u_int8_t, size_t); 25193c7b57cSdlg void x86_bus_space_mem_set_region_2(bus_space_handle_t, bus_size_t, 25293c7b57cSdlg u_int16_t, size_t); 25393c7b57cSdlg void x86_bus_space_mem_set_region_4(bus_space_handle_t, bus_size_t, 25493c7b57cSdlg u_int32_t, size_t); 25593c7b57cSdlg void x86_bus_space_mem_set_region_8(bus_space_handle_t, bus_size_t, 25693c7b57cSdlg u_int64_t, size_t); 25793c7b57cSdlg 25893c7b57cSdlg void x86_bus_space_mem_copy_1(bus_space_handle_t, bus_size_t, 25993c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 26093c7b57cSdlg void x86_bus_space_mem_copy_2(bus_space_handle_t, bus_size_t, 26193c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 26293c7b57cSdlg void x86_bus_space_mem_copy_4(bus_space_handle_t, bus_size_t, 26393c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 26493c7b57cSdlg void x86_bus_space_mem_copy_8(bus_space_handle_t, bus_size_t, 26593c7b57cSdlg bus_space_handle_t, bus_size_t, size_t); 26693c7b57cSdlg 26793c7b57cSdlg void * x86_bus_space_mem_vaddr(bus_space_handle_t); 26893c7b57cSdlg 26993c7b57cSdlg paddr_t x86_bus_space_mem_mmap(bus_addr_t, off_t, int, int); 27093c7b57cSdlg 27193c7b57cSdlg const struct x86_bus_space_ops x86_bus_space_mem_ops = { 27293c7b57cSdlg x86_bus_space_mem_read_1, 27393c7b57cSdlg x86_bus_space_mem_read_2, 27493c7b57cSdlg x86_bus_space_mem_read_4, 27593c7b57cSdlg x86_bus_space_mem_read_8, 27693c7b57cSdlg x86_bus_space_mem_read_multi_1, 27793c7b57cSdlg x86_bus_space_mem_read_multi_2, 27893c7b57cSdlg x86_bus_space_mem_read_multi_4, 27993c7b57cSdlg x86_bus_space_mem_read_multi_8, 28093c7b57cSdlg x86_bus_space_mem_read_region_1, 28193c7b57cSdlg x86_bus_space_mem_read_region_2, 28293c7b57cSdlg x86_bus_space_mem_read_region_4, 28393c7b57cSdlg x86_bus_space_mem_read_region_8, 28493c7b57cSdlg x86_bus_space_mem_write_1, 28593c7b57cSdlg x86_bus_space_mem_write_2, 28693c7b57cSdlg x86_bus_space_mem_write_4, 28793c7b57cSdlg x86_bus_space_mem_write_8, 28893c7b57cSdlg x86_bus_space_mem_write_multi_1, 28993c7b57cSdlg x86_bus_space_mem_write_multi_2, 29093c7b57cSdlg x86_bus_space_mem_write_multi_4, 29193c7b57cSdlg x86_bus_space_mem_write_multi_8, 29293c7b57cSdlg x86_bus_space_mem_write_region_1, 29393c7b57cSdlg x86_bus_space_mem_write_region_2, 29493c7b57cSdlg x86_bus_space_mem_write_region_4, 29593c7b57cSdlg x86_bus_space_mem_write_region_8, 29693c7b57cSdlg x86_bus_space_mem_set_multi_1, 29793c7b57cSdlg x86_bus_space_mem_set_multi_2, 29893c7b57cSdlg x86_bus_space_mem_set_multi_4, 29993c7b57cSdlg x86_bus_space_mem_set_multi_8, 30093c7b57cSdlg x86_bus_space_mem_set_region_1, 30193c7b57cSdlg x86_bus_space_mem_set_region_2, 30293c7b57cSdlg x86_bus_space_mem_set_region_4, 30393c7b57cSdlg x86_bus_space_mem_set_region_8, 30493c7b57cSdlg x86_bus_space_mem_copy_1, 30593c7b57cSdlg x86_bus_space_mem_copy_2, 30693c7b57cSdlg x86_bus_space_mem_copy_4, 30793c7b57cSdlg x86_bus_space_mem_copy_8, 30893c7b57cSdlg x86_bus_space_mem_vaddr, 30993c7b57cSdlg x86_bus_space_mem_mmap 31093c7b57cSdlg }; 31193c7b57cSdlg 312f5df1827Smickey void 3132bb6026aSjsg x86_bus_space_init(void) 314f5df1827Smickey { 315f5df1827Smickey /* 316f5df1827Smickey * Initialize the I/O port and I/O mem extent maps. 317f5df1827Smickey * Note: we don't have to check the return value since 318f5df1827Smickey * creation of a fixed extent map will never fail (since 319f5df1827Smickey * descriptor storage has already been allocated). 320f5df1827Smickey * 321f5df1827Smickey * N.B. The iomem extent manages _all_ physical addresses 322f5df1827Smickey * on the machine. When the amount of RAM is found, the two 323f5df1827Smickey * extents of RAM are allocated from the map (0 -> ISA hole 324f5df1827Smickey * and end of ISA hole -> end of RAM). 325f5df1827Smickey */ 326f5df1827Smickey ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF, 327f5df1827Smickey (caddr_t)ioport_ex_storage, sizeof(ioport_ex_storage), 328f5df1827Smickey EX_NOCOALESCE|EX_NOWAIT); 329ddf0857aSkettenis iomem_ex = extent_create("iomem", 0x0, 0xffffffffffff, M_DEVBUF, 330f5df1827Smickey (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), 331f5df1827Smickey EX_NOCOALESCE|EX_NOWAIT); 332f5df1827Smickey } 333f5df1827Smickey 334f5df1827Smickey void 3352bb6026aSjsg x86_bus_space_mallocok(void) 336f5df1827Smickey { 337f5df1827Smickey ioport_malloc_safe = 1; 338f5df1827Smickey } 339f5df1827Smickey 340f5df1827Smickey int 34199afcea1Sderaadt bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, 3422bb6026aSjsg bus_space_handle_t *bshp) 343f5df1827Smickey { 344f5df1827Smickey int error; 345f5df1827Smickey struct extent *ex; 346f5df1827Smickey 347f5df1827Smickey /* 348f5df1827Smickey * Pick the appropriate extent map. 349f5df1827Smickey */ 350f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 351f5df1827Smickey ex = ioport_ex; 352515b194eSmarco if (flags & BUS_SPACE_MAP_LINEAR) 353515b194eSmarco return (EINVAL); 354f5df1827Smickey } else if (t == X86_BUS_SPACE_MEM) 355f5df1827Smickey ex = iomem_ex; 356f5df1827Smickey else 35799afcea1Sderaadt panic("bus_space_map: bad bus space tag"); 358f5df1827Smickey 359f5df1827Smickey /* 360f5df1827Smickey * Before we go any further, let's make sure that this 361f5df1827Smickey * region is available. 362f5df1827Smickey */ 363f5df1827Smickey error = extent_alloc_region(ex, bpa, size, 364f5df1827Smickey EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); 365f5df1827Smickey if (error) 366f5df1827Smickey return (error); 367f5df1827Smickey 368f5df1827Smickey /* 369f5df1827Smickey * For I/O space, that's all she wrote. 370f5df1827Smickey */ 371f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 372f5df1827Smickey *bshp = bpa; 373f5df1827Smickey return (0); 374f5df1827Smickey } 375f5df1827Smickey 376f5df1827Smickey if (bpa >= IOM_BEGIN && (bpa + size) <= IOM_END) { 377f5df1827Smickey *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa); 378f5df1827Smickey return(0); 379f5df1827Smickey } 380f5df1827Smickey 381*e12dfaa1Skettenis if (!pmap_initialized && bpa < 0x100000000) { 382*e12dfaa1Skettenis *bshp = (bus_space_handle_t)PMAP_DIRECT_MAP(bpa); 383*e12dfaa1Skettenis return(0); 384*e12dfaa1Skettenis } 385*e12dfaa1Skettenis 386f5df1827Smickey /* 387f5df1827Smickey * For memory space, map the bus physical address to 388f5df1827Smickey * a kernel virtual address. 389f5df1827Smickey */ 3905bac233bSoga error = x86_mem_add_mapping(bpa, size, flags, bshp); 391f5df1827Smickey if (error) { 392f5df1827Smickey if (extent_free(ex, bpa, size, EX_NOWAIT | 393f5df1827Smickey (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 39499afcea1Sderaadt printf("bus_space_map: pa 0x%lx, size 0x%lx\n", 395f5df1827Smickey bpa, size); 39699afcea1Sderaadt printf("bus_space_map: can't free region\n"); 397f5df1827Smickey } 398f5df1827Smickey } 399f5df1827Smickey 400f5df1827Smickey return (error); 401f5df1827Smickey } 402f5df1827Smickey 403f5df1827Smickey int 40499afcea1Sderaadt _bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, 4052bb6026aSjsg bus_space_handle_t *bshp) 406f5df1827Smickey { 407f5df1827Smickey 408f5df1827Smickey /* 409f5df1827Smickey * For I/O space, just fill in the handle. 410f5df1827Smickey */ 411f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 412f5df1827Smickey *bshp = bpa; 413f5df1827Smickey return (0); 414f5df1827Smickey } 415f5df1827Smickey 416f5df1827Smickey /* 417f5df1827Smickey * For memory space, map the bus physical address to 418f5df1827Smickey * a kernel virtual address. 419f5df1827Smickey */ 4205bac233bSoga return (x86_mem_add_mapping(bpa, size, flags, bshp)); 421f5df1827Smickey } 422f5df1827Smickey 423f5df1827Smickey int 42499afcea1Sderaadt bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend, 4252bb6026aSjsg bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, 4262bb6026aSjsg bus_addr_t *bpap, bus_space_handle_t *bshp) 427f5df1827Smickey { 428f5df1827Smickey struct extent *ex; 429f5df1827Smickey u_long bpa; 430f5df1827Smickey int error; 431f5df1827Smickey 432f5df1827Smickey /* 433f5df1827Smickey * Pick the appropriate extent map. 434f5df1827Smickey */ 435f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 436f5df1827Smickey ex = ioport_ex; 437f5df1827Smickey } else if (t == X86_BUS_SPACE_MEM) 438f5df1827Smickey ex = iomem_ex; 439f5df1827Smickey else 44099afcea1Sderaadt panic("bus_space_alloc: bad bus space tag"); 441f5df1827Smickey 442f5df1827Smickey /* 443f5df1827Smickey * Sanity check the allocation against the extent's boundaries. 444f5df1827Smickey */ 445f5df1827Smickey if (rstart < ex->ex_start || rend > ex->ex_end) 44699afcea1Sderaadt panic("bus_space_alloc: bad region start/end"); 447f5df1827Smickey 448f5df1827Smickey /* 449f5df1827Smickey * Do the requested allocation. 450f5df1827Smickey */ 451f5df1827Smickey error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 452f5df1827Smickey 0, boundary, 453f5df1827Smickey EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0), 454f5df1827Smickey &bpa); 455f5df1827Smickey 456f5df1827Smickey if (error) 457f5df1827Smickey return (error); 458f5df1827Smickey 459f5df1827Smickey /* 460f5df1827Smickey * For I/O space, that's all she wrote. 461f5df1827Smickey */ 462f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 463f5df1827Smickey *bshp = *bpap = bpa; 464f5df1827Smickey return (0); 465f5df1827Smickey } 466f5df1827Smickey 467f5df1827Smickey /* 468f5df1827Smickey * For memory space, map the bus physical address to 469f5df1827Smickey * a kernel virtual address. 470f5df1827Smickey */ 4715bac233bSoga error = x86_mem_add_mapping(bpa, size, flags, bshp); 472f5df1827Smickey if (error) { 473f5df1827Smickey if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | 474f5df1827Smickey (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 47599afcea1Sderaadt printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", 476f5df1827Smickey bpa, size); 47799afcea1Sderaadt printf("bus_space_alloc: can't free region\n"); 478f5df1827Smickey } 479f5df1827Smickey } 480f5df1827Smickey 481f5df1827Smickey *bpap = bpa; 482f5df1827Smickey 483f5df1827Smickey return (error); 484f5df1827Smickey } 485f5df1827Smickey 486f5df1827Smickey int 4875bac233bSoga x86_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int flags, 4882bb6026aSjsg bus_space_handle_t *bshp) 489f5df1827Smickey { 49007dfb2ccSoga paddr_t pa, endpa; 491de00544fSoga vaddr_t va; 4925bac233bSoga bus_size_t map_size; 49307dfb2ccSoga int pmap_flags = PMAP_NOCACHE; 4945bac233bSoga 4955bac233bSoga pa = trunc_page(bpa); 4965bac233bSoga endpa = round_page(bpa + size); 4975bac233bSoga 4985bac233bSoga #ifdef DIAGNOSTIC 4995bac233bSoga if (endpa <= pa && endpa != 0) 5005bac233bSoga panic("bus_mem_add_mapping: overflow"); 5015bac233bSoga #endif 5025bac233bSoga 5035bac233bSoga map_size = endpa - pa; 5045bac233bSoga 50537d9e641Skettenis va = (vaddr_t)km_alloc(map_size, &kv_any, &kp_none, &kd_nowait); 5065bac233bSoga if (va == 0) 5075bac233bSoga return (ENOMEM); 5085bac233bSoga 5095bac233bSoga *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); 5105bac233bSoga 51107dfb2ccSoga if (flags & BUS_SPACE_MAP_CACHEABLE) 51207dfb2ccSoga pmap_flags = 0; 51307dfb2ccSoga else if (flags & BUS_SPACE_MAP_PREFETCHABLE) 51407dfb2ccSoga pmap_flags = PMAP_WC; 51507dfb2ccSoga 5165bac233bSoga for (; map_size > 0; 517de00544fSoga pa += PAGE_SIZE, va += PAGE_SIZE, map_size -= PAGE_SIZE) 5181e8cdc2eSderaadt pmap_kenter_pa(va, pa | pmap_flags, PROT_READ | PROT_WRITE); 5195bac233bSoga pmap_update(pmap_kernel()); 5205bac233bSoga 521f5df1827Smickey return 0; 522f5df1827Smickey } 523f5df1827Smickey 524f5df1827Smickey /* 52599afcea1Sderaadt * void _bus_space_unmap(bus_space_tag bst, bus_space_handle bsh, 526f5df1827Smickey * bus_size_t size, bus_addr_t *adrp) 527f5df1827Smickey * 528f5df1827Smickey * This function unmaps memory- or io-space mapped by the function 52999afcea1Sderaadt * _bus_space_map(). This function works nearly as same as 53099afcea1Sderaadt * bus_space_unmap(), but this function does not ask kernel 531f5df1827Smickey * built-in extents and returns physical address of the bus space, 532f5df1827Smickey * for the convenience of the extra extent manager. 533f5df1827Smickey */ 534f5df1827Smickey void 53599afcea1Sderaadt _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size, 5362bb6026aSjsg bus_addr_t *adrp) 537f5df1827Smickey { 5385bac233bSoga u_long va, endva; 539f5df1827Smickey bus_addr_t bpa; 540f5df1827Smickey 541f5df1827Smickey /* 5425bac233bSoga * Find the correct bus physical address. 543f5df1827Smickey */ 544f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 545f5df1827Smickey bpa = bsh; 546f5df1827Smickey } else if (t == X86_BUS_SPACE_MEM) { 547f5df1827Smickey bpa = (bus_addr_t)ISA_PHYSADDR(bsh); 5485bac233bSoga if (IOM_BEGIN <= bpa && bpa <= IOM_END) 5495bac233bSoga goto ok; 550f5df1827Smickey 5515bac233bSoga va = trunc_page(bsh); 5525bac233bSoga endva = round_page(bsh + size); 5535bac233bSoga 5545bac233bSoga #ifdef DIAGNOSTIC 5555bac233bSoga if (endva <= va) 5565bac233bSoga panic("_bus_space_unmap: overflow"); 5575bac233bSoga #endif 5585bac233bSoga 5595bac233bSoga (void) pmap_extract(pmap_kernel(), va, &bpa); 5605bac233bSoga bpa += (bsh & PGOFSET); 5615bac233bSoga 5625bac233bSoga pmap_kremove(va, endva - va); 5635bac233bSoga pmap_update(pmap_kernel()); 5645bac233bSoga 5655bac233bSoga /* 5665bac233bSoga * Free the kernel virtual mapping. 5675bac233bSoga */ 56837d9e641Skettenis km_free((void *)va, endva - va, &kv_any, &kp_none); 5695bac233bSoga } else 5705bac233bSoga panic("bus_space_unmap: bad bus space tag"); 5715bac233bSoga 5725bac233bSoga ok: 5735bac233bSoga if (adrp != NULL) 574f5df1827Smickey *adrp = bpa; 575f5df1827Smickey } 576f5df1827Smickey 577f5df1827Smickey void 57899afcea1Sderaadt bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 579f5df1827Smickey { 580f5df1827Smickey struct extent *ex; 5815bac233bSoga u_long va, endva; 582f5df1827Smickey bus_addr_t bpa; 583f5df1827Smickey 584f5df1827Smickey /* 585f5df1827Smickey * Find the correct extent and bus physical address. 586f5df1827Smickey */ 587f5df1827Smickey if (t == X86_BUS_SPACE_IO) { 588f5df1827Smickey ex = ioport_ex; 589f5df1827Smickey bpa = bsh; 590f5df1827Smickey } else if (t == X86_BUS_SPACE_MEM) { 591f5df1827Smickey ex = iomem_ex; 592f5df1827Smickey bpa = (bus_addr_t)ISA_PHYSADDR(bsh); 5935bac233bSoga if (IOM_BEGIN <= bpa && bpa <= IOM_END) 594f5df1827Smickey goto ok; 595f5df1827Smickey 596*e12dfaa1Skettenis if (bsh >= PMAP_DIRECT_BASE && bsh < PMAP_DIRECT_END) { 597*e12dfaa1Skettenis bpa = PMAP_DIRECT_UNMAP(bsh); 598*e12dfaa1Skettenis goto ok; 599*e12dfaa1Skettenis } 600*e12dfaa1Skettenis 6015bac233bSoga va = trunc_page(bsh); 6025bac233bSoga endva = round_page(bsh + size); 6035bac233bSoga 6045bac233bSoga #ifdef DIAGNOSTIC 6055bac233bSoga if (endva <= va) 6065bac233bSoga panic("bus_space_unmap: overflow"); 6075bac233bSoga #endif 6085bac233bSoga 6095bac233bSoga (void)pmap_extract(pmap_kernel(), va, &bpa); 6105bac233bSoga bpa += (bsh & PGOFSET); 6115bac233bSoga 6125bac233bSoga pmap_kremove(va, endva - va); 6135bac233bSoga pmap_update(pmap_kernel()); 6145bac233bSoga 6155bac233bSoga /* 6165bac233bSoga * Free the kernel virtual mapping. 6175bac233bSoga */ 61837d9e641Skettenis km_free((void *)va, endva - va, &kv_any, &kp_none); 619f5df1827Smickey } else 62099afcea1Sderaadt panic("bus_space_unmap: bad bus space tag"); 621f5df1827Smickey 622f5df1827Smickey ok: 623f5df1827Smickey if (extent_free(ex, bpa, size, 624f5df1827Smickey EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 62599afcea1Sderaadt printf("bus_space_unmap: %s 0x%lx, size 0x%lx\n", 626f5df1827Smickey (t == X86_BUS_SPACE_IO) ? "port" : "pa", bpa, size); 62799afcea1Sderaadt printf("bus_space_unmap: can't free region\n"); 628f5df1827Smickey } 629f5df1827Smickey } 630f5df1827Smickey 631f5df1827Smickey void 63299afcea1Sderaadt bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 633f5df1827Smickey { 634f5df1827Smickey 63599afcea1Sderaadt /* bus_space_unmap() does all that we need to do. */ 63699afcea1Sderaadt bus_space_unmap(t, bsh, size); 637f5df1827Smickey } 638f5df1827Smickey 639f5df1827Smickey int 64099afcea1Sderaadt bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 6412bb6026aSjsg bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 642f5df1827Smickey { 643f5df1827Smickey 644f5df1827Smickey *nbshp = bsh + offset; 645f5df1827Smickey return (0); 646f5df1827Smickey } 647f5df1827Smickey 648ebbaad44Soga u_int8_t 64993c7b57cSdlg x86_bus_space_io_read_1(bus_space_handle_t h, bus_size_t o) 650ebbaad44Soga { 65193c7b57cSdlg return (inb(h + o)); 652ebbaad44Soga } 653ebbaad44Soga 654ebbaad44Soga u_int16_t 65593c7b57cSdlg x86_bus_space_io_read_2(bus_space_handle_t h, bus_size_t o) 656ebbaad44Soga { 65793c7b57cSdlg return (inw(h + o)); 658ebbaad44Soga } 659ebbaad44Soga 660ebbaad44Soga u_int32_t 66193c7b57cSdlg x86_bus_space_io_read_4(bus_space_handle_t h, bus_size_t o) 662ebbaad44Soga { 66393c7b57cSdlg return (inl(h + o)); 664ebbaad44Soga } 665ebbaad44Soga 6669f2791f2Sdlg u_int64_t 66793c7b57cSdlg x86_bus_space_io_read_8(bus_space_handle_t h, bus_size_t o) 6689f2791f2Sdlg { 66993c7b57cSdlg panic("bus_space_read_8: invalid bus space tag"); 6709f2791f2Sdlg } 6719f2791f2Sdlg 672ebbaad44Soga void 67393c7b57cSdlg x86_bus_space_io_read_multi_1(bus_space_handle_t h, bus_size_t o, 674ebbaad44Soga u_int8_t *ptr, bus_size_t cnt) 675ebbaad44Soga { 676ebbaad44Soga insb(h + o, ptr, cnt); 677ebbaad44Soga } 678ebbaad44Soga 679ebbaad44Soga void 68093c7b57cSdlg x86_bus_space_io_read_multi_2(bus_space_handle_t h, bus_size_t o, 681ebbaad44Soga u_int16_t *ptr, bus_size_t cnt) 682ebbaad44Soga { 683ebbaad44Soga insw(h + o, ptr, cnt); 684ebbaad44Soga } 685ebbaad44Soga 686ebbaad44Soga void 68793c7b57cSdlg x86_bus_space_io_read_multi_4(bus_space_handle_t h, bus_size_t o, 688ebbaad44Soga u_int32_t *ptr, bus_size_t cnt) 689ebbaad44Soga { 690ebbaad44Soga insl(h + o, ptr, cnt); 691ebbaad44Soga } 692ebbaad44Soga 693ebbaad44Soga void 69493c7b57cSdlg x86_bus_space_io_read_multi_8(bus_space_handle_t h, bus_size_t o, 6959f2791f2Sdlg u_int64_t *ptr, bus_size_t cnt) 6969f2791f2Sdlg { 69793c7b57cSdlg panic("bus_space_multi_8: invalid bus space tag"); 6989f2791f2Sdlg } 6999f2791f2Sdlg 7009f2791f2Sdlg void 70193c7b57cSdlg x86_bus_space_io_read_region_1(bus_space_handle_t h, 702ebbaad44Soga bus_size_t o, u_int8_t *ptr, bus_size_t cnt) 703ebbaad44Soga { 704ebbaad44Soga int dummy1; 705ebbaad44Soga void *dummy2; 706ebbaad44Soga int dummy3; 707ebbaad44Soga int __x; 708d5e88557Sjsg u_int32_t port = h + o; 709e39f036fSguenther __asm volatile( 710ebbaad44Soga "1: inb %w1,%%al ;" 711ebbaad44Soga " stosb ;" 712ebbaad44Soga " incl %1 ;" 713ebbaad44Soga " loop 1b" : 714ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=D" (dummy2), 715ebbaad44Soga "=c" (dummy3) : 716d5e88557Sjsg "1" (port), "2" (ptr), "3" (cnt) : 717ebbaad44Soga "memory"); 718ebbaad44Soga } 719ebbaad44Soga 720ebbaad44Soga void 72193c7b57cSdlg x86_bus_space_io_read_region_2(bus_space_handle_t h, 722ebbaad44Soga bus_size_t o, u_int16_t *ptr, bus_size_t cnt) 723ebbaad44Soga { 724ebbaad44Soga int dummy1; 725ebbaad44Soga void *dummy2; 726ebbaad44Soga int dummy3; 727ebbaad44Soga int __x; 728d5e88557Sjsg u_int32_t port = h + o; 729e39f036fSguenther __asm volatile( 730ebbaad44Soga "1: inw %w1,%%ax ;" 731ebbaad44Soga " stosw ;" 732ebbaad44Soga " addl $2,%1 ;" 733ebbaad44Soga " loop 1b" : 734ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=D" (dummy2), 735ebbaad44Soga "=c" (dummy3) : 736d5e88557Sjsg "1" ((port)), "2" ((ptr)), "3" ((cnt)) : 737ebbaad44Soga "memory"); 738ebbaad44Soga } 739ebbaad44Soga 740ebbaad44Soga void 74193c7b57cSdlg x86_bus_space_io_read_region_4(bus_space_handle_t h, 742ebbaad44Soga bus_size_t o, u_int32_t *ptr, bus_size_t cnt) 743ebbaad44Soga { 744ebbaad44Soga int dummy1; 745ebbaad44Soga void *dummy2; 746ebbaad44Soga int dummy3; 747ebbaad44Soga int __x; 748d5e88557Sjsg u_int32_t port = h + o; 749e39f036fSguenther __asm volatile( 750ebbaad44Soga "1: inl %w1,%%eax ;" 751ebbaad44Soga " stosl ;" 752ebbaad44Soga " addl $4,%1 ;" 753ebbaad44Soga " loop 1b" : 754ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=D" (dummy2), 755ebbaad44Soga "=c" (dummy3) : 756d5e88557Sjsg "1" (port), "2" (ptr), "3" (cnt) : 757ebbaad44Soga "memory"); 758ebbaad44Soga } 7599f2791f2Sdlg 7609f2791f2Sdlg void 76193c7b57cSdlg x86_bus_space_io_read_region_8(bus_space_handle_t h, 7629f2791f2Sdlg bus_size_t o, u_int64_t *ptr, bus_size_t cnt) 7639f2791f2Sdlg { 76493c7b57cSdlg panic("bus_space_read_region_8: invalid bus space tag"); 7659f2791f2Sdlg } 7669f2791f2Sdlg 767ebbaad44Soga void 76893c7b57cSdlg x86_bus_space_io_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v) 769ebbaad44Soga { 770ebbaad44Soga outb(h + o, v); 771ebbaad44Soga } 772ebbaad44Soga 773ebbaad44Soga void 77493c7b57cSdlg x86_bus_space_io_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v) 775ebbaad44Soga { 776ebbaad44Soga outw(h + o, v); 777ebbaad44Soga } 778ebbaad44Soga 779ebbaad44Soga void 78093c7b57cSdlg x86_bus_space_io_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v) 781ebbaad44Soga { 782ebbaad44Soga outl(h + o, v); 783ebbaad44Soga } 784ebbaad44Soga 785ebbaad44Soga void 78693c7b57cSdlg x86_bus_space_io_write_8(bus_space_handle_t h, bus_size_t o, u_int64_t v) 7879f2791f2Sdlg { 78893c7b57cSdlg panic("bus_space_write_8: invalid bus space tag"); 7899f2791f2Sdlg } 7909f2791f2Sdlg 7919f2791f2Sdlg void 79293c7b57cSdlg x86_bus_space_io_write_multi_1(bus_space_handle_t h, 793ebbaad44Soga bus_size_t o, const u_int8_t *ptr, bus_size_t cnt) 794ebbaad44Soga { 795ebbaad44Soga outsb(h + o, ptr, cnt); 796ebbaad44Soga } 797ebbaad44Soga 798ebbaad44Soga void 79993c7b57cSdlg x86_bus_space_io_write_multi_2(bus_space_handle_t h, 800ebbaad44Soga bus_size_t o, const u_int16_t *ptr, bus_size_t cnt) 801ebbaad44Soga { 802ebbaad44Soga outsw(h + o, ptr, cnt); 803ebbaad44Soga } 804ebbaad44Soga 805ebbaad44Soga void 80693c7b57cSdlg x86_bus_space_io_write_multi_4(bus_space_handle_t h, 807ebbaad44Soga bus_size_t o, const u_int32_t *ptr, bus_size_t cnt) 808ebbaad44Soga { 809ebbaad44Soga outsl(h + o, ptr, cnt); 810ebbaad44Soga } 811ebbaad44Soga 812ebbaad44Soga void 81393c7b57cSdlg x86_bus_space_io_write_multi_8(bus_space_handle_t h, 8149f2791f2Sdlg bus_size_t o, const u_int64_t *ptr, bus_size_t cnt) 8159f2791f2Sdlg { 81693c7b57cSdlg panic("bus_space_write_multi_8: invalid bus space tag"); 8179f2791f2Sdlg } 8189f2791f2Sdlg 8199f2791f2Sdlg void 82093c7b57cSdlg x86_bus_space_io_write_region_1(bus_space_handle_t h, 821ebbaad44Soga bus_size_t o, const u_int8_t *ptr, bus_size_t cnt) 822ebbaad44Soga { 823ebbaad44Soga int dummy1; 824ebbaad44Soga void *dummy2; 825ebbaad44Soga int dummy3; 826ebbaad44Soga int __x; 827d5e88557Sjsg u_int32_t port = h + o; 828e39f036fSguenther __asm volatile( 829ebbaad44Soga "1: lodsb ;" 830ebbaad44Soga " outb %%al,%w1 ;" 831ebbaad44Soga " incl %1 ;" 832ebbaad44Soga " loop 1b" : 833ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=S" (dummy2), 834ebbaad44Soga "=c" (dummy3) : 835d5e88557Sjsg "1" (port), "2" (ptr), "3" (cnt) : 836ebbaad44Soga "memory"); 837ebbaad44Soga } 838ebbaad44Soga 839ebbaad44Soga void 84093c7b57cSdlg x86_bus_space_io_write_region_2(bus_space_handle_t h, 841ebbaad44Soga bus_size_t o, const u_int16_t *ptr, bus_size_t cnt) 842ebbaad44Soga { 843ebbaad44Soga int dummy1; 844ebbaad44Soga void *dummy2; 845ebbaad44Soga int dummy3; 846ebbaad44Soga int __x; 847d5e88557Sjsg u_int32_t port = h + o; 848e39f036fSguenther __asm volatile( 849ebbaad44Soga "1: lodsw ;" 850ebbaad44Soga " outw %%ax,%w1 ;" 851ebbaad44Soga " addl $2,%1 ;" 852ebbaad44Soga " loop 1b" : 853ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=S" (dummy2), 854ebbaad44Soga "=c" (dummy3) : 855d5e88557Sjsg "1" (port), "2" (ptr), "3" (cnt) : 856ebbaad44Soga "memory"); 857ebbaad44Soga } 858ebbaad44Soga 859ebbaad44Soga void 86093c7b57cSdlg x86_bus_space_io_write_region_4(bus_space_handle_t h, 861ebbaad44Soga bus_size_t o, const u_int32_t *ptr, bus_size_t cnt) 862ebbaad44Soga { 863ebbaad44Soga int dummy1; 864ebbaad44Soga void *dummy2; 865ebbaad44Soga int dummy3; 866ebbaad44Soga int __x; 867d5e88557Sjsg u_int32_t port = h + o; 868e39f036fSguenther __asm volatile( 869ebbaad44Soga "1: lodsl ;" 870ebbaad44Soga " outl %%eax,%w1 ;" 871ebbaad44Soga " addl $4,%1 ;" 872ebbaad44Soga " loop 1b" : 873ebbaad44Soga "=&a" (__x), "=d" (dummy1), "=S" (dummy2), 874ebbaad44Soga "=c" (dummy3) : 875d5e88557Sjsg "1" (port), "2" (ptr), "3" (cnt) : 876ebbaad44Soga "memory"); 87793c7b57cSdlg } 87893c7b57cSdlg 87993c7b57cSdlg void 88093c7b57cSdlg x86_bus_space_io_write_region_8(bus_space_handle_t h, 88193c7b57cSdlg bus_size_t o, const u_int64_t *ptr, bus_size_t cnt) 88293c7b57cSdlg { 88393c7b57cSdlg panic("bus_space_write_region_8: invalid bus space tag"); 88493c7b57cSdlg } 88593c7b57cSdlg 88693c7b57cSdlg void 88793c7b57cSdlg x86_bus_space_io_set_multi_1(bus_space_handle_t h, bus_size_t o, 88893c7b57cSdlg u_int8_t v, size_t c) 88993c7b57cSdlg { 89093c7b57cSdlg bus_addr_t addr = h + o; 89193c7b57cSdlg 89293c7b57cSdlg while (c--) 89393c7b57cSdlg outb(addr, v); 89493c7b57cSdlg } 89593c7b57cSdlg 89693c7b57cSdlg void 89793c7b57cSdlg x86_bus_space_io_set_multi_2(bus_space_handle_t h, bus_size_t o, 89893c7b57cSdlg u_int16_t v, size_t c) 89993c7b57cSdlg { 90093c7b57cSdlg bus_addr_t addr = h + o; 90193c7b57cSdlg 90293c7b57cSdlg while (c--) 90393c7b57cSdlg outw(addr, v); 90493c7b57cSdlg } 90593c7b57cSdlg 90693c7b57cSdlg void 90793c7b57cSdlg x86_bus_space_io_set_multi_4(bus_space_handle_t h, bus_size_t o, 90893c7b57cSdlg u_int32_t v, size_t c) 90993c7b57cSdlg { 91093c7b57cSdlg bus_addr_t addr = h + o; 91193c7b57cSdlg 91293c7b57cSdlg while (c--) 91393c7b57cSdlg outl(addr, v); 91493c7b57cSdlg } 91593c7b57cSdlg 91693c7b57cSdlg void 91793c7b57cSdlg x86_bus_space_io_set_multi_8(bus_space_handle_t h, bus_size_t o, 91893c7b57cSdlg u_int64_t v, size_t c) 91993c7b57cSdlg { 92093c7b57cSdlg panic("bus_space_set_multi_8: invalid bus space tag"); 92193c7b57cSdlg } 92293c7b57cSdlg 92393c7b57cSdlg void 92493c7b57cSdlg x86_bus_space_io_set_region_1(bus_space_handle_t h, bus_size_t o, 92593c7b57cSdlg u_int8_t v, size_t c) 92693c7b57cSdlg { 92793c7b57cSdlg bus_addr_t addr = h + o; 92893c7b57cSdlg 92993c7b57cSdlg for (; c != 0; c--, addr++) 93093c7b57cSdlg outb(addr, v); 93193c7b57cSdlg } 93293c7b57cSdlg 93393c7b57cSdlg void 93493c7b57cSdlg x86_bus_space_io_set_region_2(bus_space_handle_t h, bus_size_t o, 93593c7b57cSdlg u_int16_t v, size_t c) 93693c7b57cSdlg { 93793c7b57cSdlg bus_addr_t addr = h + o; 93893c7b57cSdlg 93993c7b57cSdlg for (; c != 0; c--, addr += sizeof(v)) 94093c7b57cSdlg outw(addr, v); 94193c7b57cSdlg } 94293c7b57cSdlg 94393c7b57cSdlg void 94493c7b57cSdlg x86_bus_space_io_set_region_4(bus_space_handle_t h, bus_size_t o, 94593c7b57cSdlg u_int32_t v, size_t c) 94693c7b57cSdlg { 94793c7b57cSdlg bus_addr_t addr = h + o; 94893c7b57cSdlg 94993c7b57cSdlg for (; c != 0; c--, addr += sizeof(v)) 95093c7b57cSdlg outl(addr, v); 95193c7b57cSdlg } 95293c7b57cSdlg 95393c7b57cSdlg void 95493c7b57cSdlg x86_bus_space_io_set_region_8(bus_space_handle_t h, bus_size_t o, 95593c7b57cSdlg u_int64_t v, size_t c) 95693c7b57cSdlg { 95793c7b57cSdlg panic("bus_space_set_region_8: invalid bus space tag"); 95893c7b57cSdlg } 95993c7b57cSdlg 96093c7b57cSdlg void 96193c7b57cSdlg x86_bus_space_io_copy_1(bus_space_handle_t h1, bus_size_t o1, 96293c7b57cSdlg bus_space_handle_t h2, bus_size_t o2, size_t c) 96393c7b57cSdlg { 96493c7b57cSdlg bus_addr_t addr1 = h1 + o1; 96593c7b57cSdlg bus_addr_t addr2 = h2 + o2; 96693c7b57cSdlg 96793c7b57cSdlg if (addr1 >= addr2) { 96893c7b57cSdlg /* src after dest: copy forward */ 96993c7b57cSdlg for (; c != 0; c--, addr1++, addr2++) 97093c7b57cSdlg outb(addr2, inb(addr1)); 971ebbaad44Soga } else { 97293c7b57cSdlg /* dest after src: copy backwards */ 97393c7b57cSdlg for (addr1 += (c - 1), addr2 += (c - 1); 97493c7b57cSdlg c != 0; c--, addr1--, addr2--) 97593c7b57cSdlg outb(addr2, inb(addr1)); 97693c7b57cSdlg } 97793c7b57cSdlg } 97893c7b57cSdlg 97993c7b57cSdlg void 98093c7b57cSdlg x86_bus_space_io_copy_2(bus_space_handle_t h1, bus_size_t o1, 98193c7b57cSdlg bus_space_handle_t h2, bus_size_t o2, size_t c) 98293c7b57cSdlg { 98393c7b57cSdlg bus_addr_t addr1 = h1 + o1; 98493c7b57cSdlg bus_addr_t addr2 = h2 + o2; 98593c7b57cSdlg 98693c7b57cSdlg if (addr1 >= addr2) { 98793c7b57cSdlg /* src after dest: copy forward */ 98893c7b57cSdlg for (; c != 0; c--, addr1 += 2, addr2 += 2) 98993c7b57cSdlg outw(addr2, inw(addr1)); 99093c7b57cSdlg } else { 99193c7b57cSdlg /* dest after src: copy backwards */ 99293c7b57cSdlg for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); 99393c7b57cSdlg c != 0; c--, addr1 -= 2, addr2 -= 2) 99493c7b57cSdlg outw(addr2, inw(addr1)); 99593c7b57cSdlg } 99693c7b57cSdlg } 99793c7b57cSdlg 99893c7b57cSdlg void 99993c7b57cSdlg x86_bus_space_io_copy_4(bus_space_handle_t h1, bus_size_t o1, 100093c7b57cSdlg bus_space_handle_t h2, bus_size_t o2, size_t c) 100193c7b57cSdlg { 100293c7b57cSdlg bus_addr_t addr1 = h1 + o1; 100393c7b57cSdlg bus_addr_t addr2 = h2 + o2; 100493c7b57cSdlg 100593c7b57cSdlg if (addr1 >= addr2) { 100693c7b57cSdlg /* src after dest: copy forward */ 100793c7b57cSdlg for (; c != 0; c--, addr1 += 4, addr2 += 4) 100893c7b57cSdlg outl(addr2, inl(addr1)); 100993c7b57cSdlg } else { 101093c7b57cSdlg /* dest after src: copy backwards */ 101193c7b57cSdlg for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); 101293c7b57cSdlg c != 0; c--, addr1 -= 4, addr2 -= 4) 101393c7b57cSdlg outl(addr2, inl(addr1)); 101493c7b57cSdlg } 101593c7b57cSdlg } 101693c7b57cSdlg 101793c7b57cSdlg void 101893c7b57cSdlg x86_bus_space_io_copy_8(bus_space_handle_t h1, bus_size_t o1, 101993c7b57cSdlg bus_space_handle_t h2, bus_size_t o2, size_t c) 102093c7b57cSdlg { 102193c7b57cSdlg panic("bus_space_set_region_8: invalid bus space tag"); 102293c7b57cSdlg } 102393c7b57cSdlg 102493c7b57cSdlg void * 102593c7b57cSdlg x86_bus_space_io_vaddr(bus_space_handle_t h) 102693c7b57cSdlg { 102793c7b57cSdlg return (NULL); 102893c7b57cSdlg } 102993c7b57cSdlg 103093c7b57cSdlg paddr_t 103193c7b57cSdlg x86_bus_space_io_mmap(bus_addr_t addr, off_t off, int prot, int flags) 103293c7b57cSdlg { 103393c7b57cSdlg /* Can't mmap I/O space. */ 103493c7b57cSdlg return (-1); 103593c7b57cSdlg } 103693c7b57cSdlg 103793c7b57cSdlg void 103893c7b57cSdlg x86_bus_space_mem_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v) 103993c7b57cSdlg { 104093c7b57cSdlg *(volatile u_int8_t *)(h + o) = v; 104193c7b57cSdlg } 104293c7b57cSdlg 104393c7b57cSdlg void 104493c7b57cSdlg x86_bus_space_mem_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v) 104593c7b57cSdlg { 104693c7b57cSdlg *(volatile u_int16_t *)(h + o) = v; 104793c7b57cSdlg } 104893c7b57cSdlg 104993c7b57cSdlg u_int8_t 105093c7b57cSdlg x86_bus_space_mem_read_1(bus_space_handle_t h, bus_size_t o) 105193c7b57cSdlg { 105293c7b57cSdlg return (*(volatile u_int8_t *)(h + o)); 105393c7b57cSdlg } 105493c7b57cSdlg 105593c7b57cSdlg u_int16_t 105693c7b57cSdlg x86_bus_space_mem_read_2(bus_space_handle_t h, bus_size_t o) 105793c7b57cSdlg { 105893c7b57cSdlg return (*(volatile u_int16_t *)(h + o)); 105993c7b57cSdlg } 106093c7b57cSdlg 106193c7b57cSdlg u_int32_t 106293c7b57cSdlg x86_bus_space_mem_read_4(bus_space_handle_t h, bus_size_t o) 106393c7b57cSdlg { 106493c7b57cSdlg return (*(volatile u_int32_t *)(h + o)); 106593c7b57cSdlg } 106693c7b57cSdlg 106793c7b57cSdlg u_int64_t 106893c7b57cSdlg x86_bus_space_mem_read_8(bus_space_handle_t h, bus_size_t o) 106993c7b57cSdlg { 107093c7b57cSdlg return (*(volatile u_int64_t *)(h + o)); 107193c7b57cSdlg } 107293c7b57cSdlg 107393c7b57cSdlg void 107493c7b57cSdlg x86_bus_space_mem_read_multi_1(bus_space_handle_t h, bus_size_t o, 107593c7b57cSdlg u_int8_t *ptr, bus_size_t cnt) 107693c7b57cSdlg { 107793c7b57cSdlg void *dummy1; 107893c7b57cSdlg int dummy2; 107993c7b57cSdlg void *dummy3; 108093c7b57cSdlg int __x; 1081e39f036fSguenther __asm volatile( 108293c7b57cSdlg "1: movb (%2),%%al ;" 108393c7b57cSdlg " stosb ;" 108493c7b57cSdlg " loop 1b" : 108593c7b57cSdlg "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 108693c7b57cSdlg "0" ((ptr)), "1" ((cnt)), "2" (h + o) : 108793c7b57cSdlg "memory"); 108893c7b57cSdlg } 108993c7b57cSdlg 109093c7b57cSdlg void 109193c7b57cSdlg x86_bus_space_mem_read_multi_2(bus_space_handle_t h, bus_size_t o, 109293c7b57cSdlg u_int16_t *ptr, bus_size_t cnt) 109393c7b57cSdlg { 109493c7b57cSdlg void *dummy1; 109593c7b57cSdlg int dummy2; 109693c7b57cSdlg void *dummy3; 109793c7b57cSdlg int __x; 1098e39f036fSguenther __asm volatile( 109993c7b57cSdlg "1: movw (%2),%%ax ;" 110093c7b57cSdlg " stosw ;" 110193c7b57cSdlg " loop 1b" : 110293c7b57cSdlg "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 110393c7b57cSdlg "0" ((ptr)), "1" ((cnt)), "2" (h + o) : 110493c7b57cSdlg "memory"); 110593c7b57cSdlg } 110693c7b57cSdlg 110793c7b57cSdlg void 110893c7b57cSdlg x86_bus_space_mem_read_multi_4(bus_space_handle_t h, bus_size_t o, 110993c7b57cSdlg u_int32_t *ptr, bus_size_t cnt) 111093c7b57cSdlg { 111193c7b57cSdlg void *dummy1; 111293c7b57cSdlg int dummy2; 111393c7b57cSdlg void *dummy3; 111493c7b57cSdlg int __x; 1115e39f036fSguenther __asm volatile( 111693c7b57cSdlg "1: movl (%2),%%eax ;" 111793c7b57cSdlg " stosl ;" 111893c7b57cSdlg " loop 1b" : 111993c7b57cSdlg "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 112093c7b57cSdlg "0" ((ptr)), "1" ((cnt)), "2" (h + o) : 112193c7b57cSdlg "memory"); 112293c7b57cSdlg } 112393c7b57cSdlg 112493c7b57cSdlg void 112593c7b57cSdlg x86_bus_space_mem_read_multi_8(bus_space_handle_t h, bus_size_t o, 112693c7b57cSdlg u_int64_t *ptr, bus_size_t cnt) 112793c7b57cSdlg { 112893c7b57cSdlg void *dummy1; 112993c7b57cSdlg int dummy2; 113093c7b57cSdlg void *dummy3; 113193c7b57cSdlg int __x; 1132e39f036fSguenther __asm volatile( 113393c7b57cSdlg "1: movq (%2),%%rax ;" 113493c7b57cSdlg " stosq ;" 113593c7b57cSdlg " loop 1b" : 113693c7b57cSdlg "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 113793c7b57cSdlg "0" ((ptr)), "1" ((cnt)), "2" (h + o) : 113893c7b57cSdlg "memory"); 113993c7b57cSdlg } 114093c7b57cSdlg 114193c7b57cSdlg void 114293c7b57cSdlg x86_bus_space_mem_read_region_1(bus_space_handle_t h, 114393c7b57cSdlg bus_size_t o, u_int8_t *ptr, bus_size_t cnt) 114493c7b57cSdlg { 114593c7b57cSdlg int dummy1; 114693c7b57cSdlg void *dummy2; 114793c7b57cSdlg int dummy3; 1148e39f036fSguenther __asm volatile( 114993c7b57cSdlg " repne ;" 115093c7b57cSdlg " movsb" : 115193c7b57cSdlg "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) : 115293c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 115393c7b57cSdlg "memory"); 115493c7b57cSdlg } 115593c7b57cSdlg 115693c7b57cSdlg void 115793c7b57cSdlg x86_bus_space_mem_read_region_2(bus_space_handle_t h, 115893c7b57cSdlg bus_size_t o, u_int16_t *ptr, bus_size_t cnt) 115993c7b57cSdlg { 116093c7b57cSdlg int dummy1; 116193c7b57cSdlg void *dummy2; 116293c7b57cSdlg int dummy3; 1163e39f036fSguenther __asm volatile( 116493c7b57cSdlg " repne ;" 116593c7b57cSdlg " movsw" : 116693c7b57cSdlg "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) : 116793c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 116893c7b57cSdlg "memory"); 116993c7b57cSdlg } 117093c7b57cSdlg 117193c7b57cSdlg void 117293c7b57cSdlg x86_bus_space_mem_read_region_4(bus_space_handle_t h, 117393c7b57cSdlg bus_size_t o, u_int32_t *ptr, bus_size_t cnt) 117493c7b57cSdlg { 117593c7b57cSdlg int dummy1; 117693c7b57cSdlg void *dummy2; 117793c7b57cSdlg int dummy3; 1178e39f036fSguenther __asm volatile( 117993c7b57cSdlg " repne ;" 118093c7b57cSdlg " movsl" : 118193c7b57cSdlg "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) : 118293c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 118393c7b57cSdlg "memory"); 118493c7b57cSdlg } 118593c7b57cSdlg 118693c7b57cSdlg void 118793c7b57cSdlg x86_bus_space_mem_read_region_8(bus_space_handle_t h, 118893c7b57cSdlg bus_size_t o, u_int64_t *ptr, bus_size_t cnt) 118993c7b57cSdlg { 119093c7b57cSdlg int dummy1; 119193c7b57cSdlg void *dummy2; 119293c7b57cSdlg int dummy3; 1193e39f036fSguenther __asm volatile( 119493c7b57cSdlg " repne ;" 119593c7b57cSdlg " movsq" : 119693c7b57cSdlg "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) : 119793c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 119893c7b57cSdlg "memory"); 119993c7b57cSdlg } 120093c7b57cSdlg 120193c7b57cSdlg void 120293c7b57cSdlg x86_bus_space_mem_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v) 120393c7b57cSdlg { 120493c7b57cSdlg *(volatile u_int32_t *)(h + o) = v; 120593c7b57cSdlg } 120693c7b57cSdlg 120793c7b57cSdlg void 120893c7b57cSdlg x86_bus_space_mem_write_8(bus_space_handle_t h, bus_size_t o, u_int64_t v) 120993c7b57cSdlg { 121093c7b57cSdlg *(volatile u_int64_t *)(h + o) = v; 121193c7b57cSdlg } 121293c7b57cSdlg 121393c7b57cSdlg void 121493c7b57cSdlg x86_bus_space_mem_write_multi_1(bus_space_handle_t h, 121593c7b57cSdlg bus_size_t o, const u_int8_t *ptr, bus_size_t cnt) 121693c7b57cSdlg { 121793c7b57cSdlg void *dummy1; 121893c7b57cSdlg int dummy2; 121993c7b57cSdlg void *dummy3; 122093c7b57cSdlg int __x; 1221e39f036fSguenther __asm volatile( 122293c7b57cSdlg "1: lodsb ;" 122393c7b57cSdlg " movb %%al,(%2) ;" 122493c7b57cSdlg " loop 1b" : 122593c7b57cSdlg "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 122693c7b57cSdlg "0" (ptr), "1" (cnt), "2" (h + o)); 122793c7b57cSdlg } 122893c7b57cSdlg 122993c7b57cSdlg void 123093c7b57cSdlg x86_bus_space_mem_write_multi_2(bus_space_handle_t h, 123193c7b57cSdlg bus_size_t o, const u_int16_t *ptr, bus_size_t cnt) 123293c7b57cSdlg { 123393c7b57cSdlg void *dummy1; 123493c7b57cSdlg int dummy2; 123593c7b57cSdlg void *dummy3; 123693c7b57cSdlg int __x; 1237e39f036fSguenther __asm volatile( 123893c7b57cSdlg "1: lodsw ;" 123993c7b57cSdlg " movw %%ax,(%2) ;" 124093c7b57cSdlg " loop 1b" : 124193c7b57cSdlg "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 124293c7b57cSdlg "0" (ptr), "1" (cnt), "2" (h + o)); 124393c7b57cSdlg } 124493c7b57cSdlg 124593c7b57cSdlg void 124693c7b57cSdlg x86_bus_space_mem_write_multi_4(bus_space_handle_t h, 124793c7b57cSdlg bus_size_t o, const u_int32_t *ptr, bus_size_t cnt) 124893c7b57cSdlg { 124993c7b57cSdlg void *dummy1; 125093c7b57cSdlg int dummy2; 125193c7b57cSdlg void *dummy3; 125293c7b57cSdlg int __x; 1253e39f036fSguenther __asm volatile( 125493c7b57cSdlg "1: lodsl ;" 125593c7b57cSdlg " movl %%eax,(%2) ;" 125693c7b57cSdlg " loop 1b" : 125793c7b57cSdlg "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 125893c7b57cSdlg "0" (ptr), "1" (cnt), "2" (h + o)); 125993c7b57cSdlg } 126093c7b57cSdlg 126193c7b57cSdlg void 126293c7b57cSdlg x86_bus_space_mem_write_multi_8(bus_space_handle_t h, 126393c7b57cSdlg bus_size_t o, const u_int64_t *ptr, bus_size_t cnt) 126493c7b57cSdlg { 126593c7b57cSdlg void *dummy1; 126693c7b57cSdlg int dummy2; 126793c7b57cSdlg void *dummy3; 126893c7b57cSdlg int __x; 1269e39f036fSguenther __asm volatile( 127093c7b57cSdlg "1: lodsq ;" 127193c7b57cSdlg " movq %%rax,(%2) ;" 127293c7b57cSdlg " loop 1b" : 127393c7b57cSdlg "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : 127493c7b57cSdlg "0" (ptr), "1" (cnt), "2" (h + o)); 127593c7b57cSdlg } 127693c7b57cSdlg 127793c7b57cSdlg void 127893c7b57cSdlg x86_bus_space_mem_write_region_1(bus_space_handle_t h, 127993c7b57cSdlg bus_size_t o, const u_int8_t *ptr, bus_size_t cnt) 128093c7b57cSdlg { 128193c7b57cSdlg int dummy1; 128293c7b57cSdlg void *dummy2; 128393c7b57cSdlg int dummy3; 1284e39f036fSguenther __asm volatile( 128593c7b57cSdlg " repne ;" 128693c7b57cSdlg " movsb" : 128793c7b57cSdlg "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) : 128893c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 128993c7b57cSdlg "memory"); 129093c7b57cSdlg } 129193c7b57cSdlg 129293c7b57cSdlg void 129393c7b57cSdlg x86_bus_space_mem_write_region_2(bus_space_handle_t h, 129493c7b57cSdlg bus_size_t o, const u_int16_t *ptr, bus_size_t cnt) 129593c7b57cSdlg { 129693c7b57cSdlg int dummy1; 129793c7b57cSdlg void *dummy2; 129893c7b57cSdlg int dummy3; 1299e39f036fSguenther __asm volatile( 130093c7b57cSdlg " repne ;" 130193c7b57cSdlg " movsw" : 130293c7b57cSdlg "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) : 130393c7b57cSdlg "0" (h + o), "1" (ptr), "2" (cnt) : 130493c7b57cSdlg "memory"); 130593c7b57cSdlg } 130693c7b57cSdlg 130793c7b57cSdlg void 130893c7b57cSdlg x86_bus_space_mem_write_region_4(bus_space_handle_t h, 130993c7b57cSdlg bus_size_t o, const u_int32_t *ptr, bus_size_t cnt) 131093c7b57cSdlg { 1311ebbaad44Soga int dummy1; 1312ebbaad44Soga void *dummy2; 1313ebbaad44Soga int dummy3; 1314e39f036fSguenther __asm volatile( 1315ebbaad44Soga " repne ;" 1316ebbaad44Soga " movsl" : 1317ebbaad44Soga "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) : 1318ebbaad44Soga "0" (h + o), "1" (ptr), "2" (cnt) : 1319ebbaad44Soga "memory"); 1320ebbaad44Soga } 1321ebbaad44Soga 1322ebbaad44Soga void 132393c7b57cSdlg x86_bus_space_mem_write_region_8(bus_space_handle_t h, 13249f2791f2Sdlg bus_size_t o, const u_int64_t *ptr, bus_size_t cnt) 13259f2791f2Sdlg { 13269f2791f2Sdlg int dummy1; 13279f2791f2Sdlg void *dummy2; 13289f2791f2Sdlg int dummy3; 1329e39f036fSguenther __asm volatile( 13309f2791f2Sdlg " repne ;" 13319f2791f2Sdlg " movsq" : 13329f2791f2Sdlg "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) : 13339f2791f2Sdlg "0" (h + o), "1" (ptr), "2" (cnt) : 13349f2791f2Sdlg "memory"); 13359f2791f2Sdlg } 13369f2791f2Sdlg 13379f2791f2Sdlg void 133893c7b57cSdlg x86_bus_space_mem_set_multi_1(bus_space_handle_t h, bus_size_t o, 1339ebbaad44Soga u_int8_t v, size_t c) 1340ebbaad44Soga { 1341ebbaad44Soga bus_addr_t addr = h + o; 1342ebbaad44Soga 1343ebbaad44Soga while (c--) 1344ebbaad44Soga *(volatile u_int8_t *)(addr) = v; 1345ebbaad44Soga } 1346ebbaad44Soga 1347ebbaad44Soga void 134893c7b57cSdlg x86_bus_space_mem_set_multi_2(bus_space_handle_t h, bus_size_t o, 1349ebbaad44Soga u_int16_t v, size_t c) 1350ebbaad44Soga { 1351ebbaad44Soga bus_addr_t addr = h + o; 1352ebbaad44Soga 1353ebbaad44Soga while (c--) 1354ebbaad44Soga *(volatile u_int16_t *)(addr) = v; 1355ebbaad44Soga } 1356ebbaad44Soga 1357ebbaad44Soga void 135893c7b57cSdlg x86_bus_space_mem_set_multi_4(bus_space_handle_t h, bus_size_t o, 1359ebbaad44Soga u_int32_t v, size_t c) 1360ebbaad44Soga { 1361ebbaad44Soga bus_addr_t addr = h + o; 1362ebbaad44Soga 1363ebbaad44Soga while (c--) 1364ebbaad44Soga *(volatile u_int32_t *)(addr) = v; 1365ebbaad44Soga } 1366ebbaad44Soga 1367ebbaad44Soga void 136893c7b57cSdlg x86_bus_space_mem_set_multi_8(bus_space_handle_t h, bus_size_t o, 13699f2791f2Sdlg u_int64_t v, size_t c) 13709f2791f2Sdlg { 13719f2791f2Sdlg bus_addr_t addr = h + o; 13729f2791f2Sdlg 13739f2791f2Sdlg while (c--) 13749f2791f2Sdlg *(volatile u_int64_t *)(addr) = v; 13759f2791f2Sdlg } 13769f2791f2Sdlg 13779f2791f2Sdlg void 137893c7b57cSdlg x86_bus_space_mem_set_region_1(bus_space_handle_t h, bus_size_t o, 1379ebbaad44Soga u_int8_t v, size_t c) 1380ebbaad44Soga { 1381ebbaad44Soga bus_addr_t addr = h + o; 1382ebbaad44Soga 1383ebbaad44Soga for (; c != 0; c--, addr++) 1384ebbaad44Soga *(volatile u_int8_t *)(addr) = v; 1385ebbaad44Soga } 1386ebbaad44Soga 1387ebbaad44Soga void 138893c7b57cSdlg x86_bus_space_mem_set_region_2(bus_space_handle_t h, bus_size_t o, 1389ebbaad44Soga u_int16_t v, size_t c) 1390ebbaad44Soga { 1391ebbaad44Soga bus_addr_t addr = h + o; 1392ebbaad44Soga 139393c7b57cSdlg for (; c != 0; c--, addr += sizeof(v)) 1394ebbaad44Soga *(volatile u_int16_t *)(addr) = v; 1395ebbaad44Soga } 1396ebbaad44Soga 1397ebbaad44Soga void 139893c7b57cSdlg x86_bus_space_mem_set_region_4(bus_space_handle_t h, bus_size_t o, 1399ebbaad44Soga u_int32_t v, size_t c) 1400ebbaad44Soga { 1401ebbaad44Soga bus_addr_t addr = h + o; 1402ebbaad44Soga 140393c7b57cSdlg for (; c != 0; c--, addr += sizeof(v)) 1404ebbaad44Soga *(volatile u_int32_t *)(addr) = v; 1405ebbaad44Soga } 1406ebbaad44Soga 1407ebbaad44Soga void 140893c7b57cSdlg x86_bus_space_mem_set_region_8(bus_space_handle_t h, bus_size_t o, 14099f2791f2Sdlg u_int64_t v, size_t c) 14109f2791f2Sdlg { 14119f2791f2Sdlg bus_addr_t addr = h + o; 14129f2791f2Sdlg 14139f2791f2Sdlg for (; c != 0; c--, addr += sizeof(v)) 14149f2791f2Sdlg *(volatile u_int64_t *)(addr) = v; 14159f2791f2Sdlg } 14169f2791f2Sdlg 14179f2791f2Sdlg void 141893c7b57cSdlg x86_bus_space_mem_copy_1( bus_space_handle_t h1, bus_size_t o1, 1419ebbaad44Soga bus_space_handle_t h2, bus_size_t o2, size_t c) 1420ebbaad44Soga { 1421ebbaad44Soga bus_addr_t addr1 = h1 + o1; 1422ebbaad44Soga bus_addr_t addr2 = h2 + o2; 1423ebbaad44Soga 1424ebbaad44Soga if (addr1 >= addr2) { 1425ebbaad44Soga /* src after dest: copy forward */ 1426ebbaad44Soga for (; c != 0; c--, addr1++, addr2++) 1427ebbaad44Soga *(volatile u_int8_t *)(addr2) = 1428ebbaad44Soga *(volatile u_int8_t *)(addr1); 1429ebbaad44Soga } else { 1430ebbaad44Soga /* dest after src: copy backwards */ 1431ebbaad44Soga for (addr1 += (c - 1), addr2 += (c - 1); 1432ebbaad44Soga c != 0; c--, addr1--, addr2--) 1433ebbaad44Soga *(volatile u_int8_t *)(addr2) = 1434ebbaad44Soga *(volatile u_int8_t *)(addr1); 1435ebbaad44Soga } 1436ebbaad44Soga } 1437ebbaad44Soga 1438ebbaad44Soga void 143993c7b57cSdlg x86_bus_space_mem_copy_2(bus_space_handle_t h1, bus_size_t o1, 1440ebbaad44Soga bus_space_handle_t h2, bus_size_t o2, size_t c) 1441ebbaad44Soga { 1442ebbaad44Soga bus_addr_t addr1 = h1 + o1; 1443ebbaad44Soga bus_addr_t addr2 = h2 + o2; 1444ebbaad44Soga 1445ebbaad44Soga if (addr1 >= addr2) { 1446ebbaad44Soga /* src after dest: copy forward */ 1447ebbaad44Soga for (; c != 0; c--, addr1 += 2, addr2 += 2) 1448ebbaad44Soga *(volatile u_int16_t *)(addr2) = 1449ebbaad44Soga *(volatile u_int16_t *)(addr1); 1450ebbaad44Soga } else { 1451ebbaad44Soga /* dest after src: copy backwards */ 1452ebbaad44Soga for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); 1453ebbaad44Soga c != 0; c--, addr1 -= 2, addr2 -= 2) 1454ebbaad44Soga *(volatile u_int16_t *)(addr2) = 1455ebbaad44Soga *(volatile u_int16_t *)(addr1); 1456ebbaad44Soga } 1457ebbaad44Soga } 1458ebbaad44Soga 1459ebbaad44Soga void 146093c7b57cSdlg x86_bus_space_mem_copy_4(bus_space_handle_t h1, bus_size_t o1, 1461ebbaad44Soga bus_space_handle_t h2, bus_size_t o2, size_t c) 1462ebbaad44Soga { 1463ebbaad44Soga bus_addr_t addr1 = h1 + o1; 1464ebbaad44Soga bus_addr_t addr2 = h2 + o2; 1465ebbaad44Soga 1466ebbaad44Soga if (addr1 >= addr2) { 1467ebbaad44Soga /* src after dest: copy forward */ 1468ebbaad44Soga for (; c != 0; c--, addr1 += 4, addr2 += 4) 1469ebbaad44Soga *(volatile u_int32_t *)(addr2) = 1470ebbaad44Soga *(volatile u_int32_t *)(addr1); 1471ebbaad44Soga } else { 1472ebbaad44Soga /* dest after src: copy backwards */ 1473ebbaad44Soga for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); 1474ebbaad44Soga c != 0; c--, addr1 -= 4, addr2 -= 4) 1475ebbaad44Soga *(volatile u_int32_t *)(addr2) = 1476ebbaad44Soga *(volatile u_int32_t *)(addr1); 1477ebbaad44Soga } 1478ebbaad44Soga } 1479ebbaad44Soga 1480ebbaad44Soga void 148193c7b57cSdlg x86_bus_space_mem_copy_8(bus_space_handle_t h1, bus_size_t o1, 14829f2791f2Sdlg bus_space_handle_t h2, bus_size_t o2, size_t c) 14839f2791f2Sdlg { 14849f2791f2Sdlg bus_addr_t addr1 = h1 + o1; 14859f2791f2Sdlg bus_addr_t addr2 = h2 + o2; 14869f2791f2Sdlg 14879f2791f2Sdlg if (addr1 >= addr2) { 14889f2791f2Sdlg /* src after dest: copy forward */ 14899f2791f2Sdlg for (; c != 0; c--, addr1 += 8, addr2 += 8) 14909f2791f2Sdlg *(volatile u_int64_t *)(addr2) = 14919f2791f2Sdlg *(volatile u_int64_t *)(addr1); 14929f2791f2Sdlg } else { 14939f2791f2Sdlg /* dest after src: copy backwards */ 14949f2791f2Sdlg for (addr1 += 8 * (c - 1), addr2 += 8 * (c - 1); 14959f2791f2Sdlg c != 0; c--, addr1 -= 8, addr2 -= 8) 14969f2791f2Sdlg *(volatile u_int64_t *)(addr2) = 14979f2791f2Sdlg *(volatile u_int64_t *)(addr1); 14989f2791f2Sdlg } 14999f2791f2Sdlg } 15009f2791f2Sdlg 150193c7b57cSdlg void * 150293c7b57cSdlg x86_bus_space_mem_vaddr(bus_space_handle_t h) 1503ebbaad44Soga { 150493c7b57cSdlg return ((void *)h); 1505ebbaad44Soga } 1506ebbaad44Soga 150793c7b57cSdlg paddr_t 150893c7b57cSdlg x86_bus_space_mem_mmap(bus_addr_t addr, off_t off, int prot, int flags) 150993c7b57cSdlg { 151093c7b57cSdlg /* 151193c7b57cSdlg * "addr" is the base address of the device we're mapping. 151293c7b57cSdlg * "off" is the offset into that device. 151393c7b57cSdlg * 151493c7b57cSdlg * Note we are called for each "page" in the device that 151593c7b57cSdlg * the upper layers want to map. 151693c7b57cSdlg */ 151793c7b57cSdlg return (addr + off); 151893c7b57cSdlg } 1519