1/*- 2 * Copyright (c) 2009 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/types.h> 31#include <machine/bus.h> 32#include <vm/vm.h> 33#include <vm/pmap.h> 34 35extern u_long ia64_port_base; 36 37#define __PIO_ADDR(port) \ 38 (void *)(ia64_port_base | (((port) & 0xfffc) << 10) | ((port) & 0xFFF)) 39 40int 41bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, 42 int flags __unused, bus_space_handle_t *bshp) 43{ 44 45 *bshp = (__predict_false(bst == IA64_BUS_SPACE_IO)) 46 ? addr : (uintptr_t)pmap_mapdev(addr, size); 47 return (0); 48} 49 50 51void 52bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh, 53 bus_size_t size) 54{ 55 56 pmap_unmapdev(bsh, size); 57} 58 59uint8_t 60bus_space_read_io_1(u_long port) 61{ 62 uint8_t v; 63 64 ia64_mf(); 65 v = ia64_ld1(__PIO_ADDR(port)); 66 ia64_mf_a(); 67 ia64_mf(); 68 return (v); 69} 70 71uint16_t 72bus_space_read_io_2(u_long port) 73{ 74 uint16_t v; 75 76 ia64_mf(); 77 v = ia64_ld2(__PIO_ADDR(port)); 78 ia64_mf_a(); 79 ia64_mf(); 80 return (v); 81} 82 83uint32_t 84bus_space_read_io_4(u_long port) 85{ 86 uint32_t v; 87 88 ia64_mf(); 89 v = ia64_ld4(__PIO_ADDR(port)); 90 ia64_mf_a(); 91 ia64_mf(); 92 return (v); 93} 94 95#if 0 96uint64_t 97bus_space_read_io_8(u_long port) 98{ 99} 100#endif 101 102void 103bus_space_write_io_1(u_long port, uint8_t val) 104{ 105 106 ia64_mf(); 107 ia64_st1(__PIO_ADDR(port), val); 108 ia64_mf_a(); 109 ia64_mf(); 110} 111 112void 113bus_space_write_io_2(u_long port, uint16_t val) 114{ 115 116 ia64_mf(); 117 ia64_st2(__PIO_ADDR(port), val); 118 ia64_mf_a(); 119 ia64_mf(); 120} 121 122void 123bus_space_write_io_4(u_long port, uint32_t val) 124{ 125 126 ia64_mf(); 127 ia64_st4(__PIO_ADDR(port), val); 128 ia64_mf_a(); 129 ia64_mf(); 130} 131 132#if 0 133void 134bus_space_write_io_8(u_long port, uint64_t val) 135{ 136} 137#endif 138 139void 140bus_space_read_multi_io_1(u_long port, uint8_t *ptr, size_t count) 141{ 142 143 while (count-- > 0) 144 *ptr++ = bus_space_read_io_1(port); 145} 146 147void 148bus_space_read_multi_io_2(u_long port, uint16_t *ptr, size_t count) 149{ 150 151 while (count-- > 0) 152 *ptr++ = bus_space_read_io_2(port); 153} 154 155void 156bus_space_read_multi_io_4(u_long port, uint32_t *ptr, size_t count) 157{ 158 159 while (count-- > 0) 160 *ptr++ = bus_space_read_io_4(port); 161} 162 163#if 0 164void 165bus_space_read_multi_io_8(u_long port, uint64_t *ptr, size_t count) 166{ 167} 168#endif 169 170void 171bus_space_write_multi_io_1(u_long port, const uint8_t *ptr, size_t count) 172{ 173 174 while (count-- > 0) 175 bus_space_write_io_1(port, *ptr++); 176} 177 178void 179bus_space_write_multi_io_2(u_long port, const uint16_t *ptr, size_t count) 180{ 181 182 while (count-- > 0) 183 bus_space_write_io_2(port, *ptr++); 184} 185 186void 187bus_space_write_multi_io_4(u_long port, const uint32_t *ptr, size_t count) 188{ 189 190 while (count-- > 0) 191 bus_space_write_io_4(port, *ptr++); 192} 193 194#if 0 195void 196bus_space_write_multi_io_8(u_long port, const uint64_t *ptr, size_t count) 197{ 198} 199#endif 200 201void 202bus_space_read_region_io_1(u_long port, uint8_t *ptr, size_t count) 203{ 204 205 while (count-- > 0) { 206 *ptr++ = bus_space_read_io_1(port); 207 port += 1; 208 } 209} 210 211void 212bus_space_read_region_io_2(u_long port, uint16_t *ptr, size_t count) 213{ 214 215 while (count-- > 0) { 216 *ptr++ = bus_space_read_io_2(port); 217 port += 2; 218 } 219} 220 221void 222bus_space_read_region_io_4(u_long port, uint32_t *ptr, size_t count) 223{ 224 225 while (count-- > 0) { 226 *ptr++ = bus_space_read_io_4(port); 227 port += 4; 228 } 229} 230 231#if 0 232void bus_space_read_region_io_8(u_long, uint64_t *, size_t); 233#endif 234 235void 236bus_space_write_region_io_1(u_long port, const uint8_t *ptr, size_t count) 237{ 238 239 while (count-- > 0) { 240 bus_space_write_io_1(port, *ptr++); 241 port += 1; 242 } 243} 244 245void 246bus_space_write_region_io_2(u_long port, const uint16_t *ptr, size_t count) 247{ 248 249 while (count-- > 0) { 250 bus_space_write_io_2(port, *ptr++); 251 port += 2; 252 } 253} 254 255void 256bus_space_write_region_io_4(u_long port, const uint32_t *ptr, size_t count) 257{ 258 259 while (count-- > 0) { 260 bus_space_write_io_4(port, *ptr++); 261 port += 4; 262 } 263} 264 265#if 0 266void 267bus_space_write_region_io_8(u_long port, const uint64_t *ptr, size_t count) 268{ 269} 270#endif 271 272void 273bus_space_set_region_io_1(u_long port, uint8_t val, size_t count) 274{ 275 276 while (count-- > 0) { 277 bus_space_write_io_1(port, val); 278 port += 1; 279 } 280} 281 282void 283bus_space_set_region_io_2(u_long port, uint16_t val, size_t count) 284{ 285 286 while (count-- > 0) { 287 bus_space_write_io_2(port, val); 288 port += 2; 289 } 290} 291 292void 293bus_space_set_region_io_4(u_long port, uint32_t val, size_t count) 294{ 295 296 while (count-- > 0) { 297 bus_space_write_io_4(port, val); 298 port += 4; 299 } 300} 301 302#if 0 303void 304bus_space_set_region_io_8(u_long port, uint64_t val, size_t count) 305{ 306} 307#endif 308 309void 310bus_space_copy_region_io_1(u_long src, u_long dst, size_t count) 311{ 312 long delta; 313 uint8_t val; 314 315 if (src < dst) { 316 src += count - 1; 317 dst += count - 1; 318 delta = -1; 319 } else 320 delta = 1; 321 322 while (count-- > 0) { 323 val = bus_space_read_io_1(src); 324 bus_space_write_io_1(dst, val); 325 src += delta; 326 dst += delta; 327 } 328} 329 330void 331bus_space_copy_region_io_2(u_long src, u_long dst, size_t count) 332{ 333 long delta; 334 uint16_t val; 335 336 if (src < dst) { 337 src += 2 * (count - 1); 338 dst += 2 * (count - 1); 339 delta = -2; 340 } else 341 delta = 2; 342 343 while (count-- > 0) { 344 val = bus_space_read_io_2(src); 345 bus_space_write_io_2(dst, val); 346 src += delta; 347 dst += delta; 348 } 349} 350 351void 352bus_space_copy_region_io_4(u_long src, u_long dst, size_t count) 353{ 354 long delta; 355 uint32_t val; 356 357 if (src < dst) { 358 src += 4 * (count - 1); 359 dst += 4 * (count - 1); 360 delta = -4; 361 } else 362 delta = 4; 363 364 while (count-- > 0) { 365 val = bus_space_read_io_4(src); 366 bus_space_write_io_4(dst, val); 367 src += delta; 368 dst += delta; 369 } 370} 371 372#if 0 373void 374bus_space_copy_region_io_8(u_long src, u_long dst, size_t count) 375{ 376} 377#endif 378