1/* $NetBSD: busfunc.S,v 1.9 2013/06/22 05:20:57 uebayasi Exp $ */ 2 3/*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <machine/asm.h> 33__KERNEL_RCSID(0, "$NetBSD: busfunc.S,v 1.9 2013/06/22 05:20:57 uebayasi Exp $"); 34 35#include "assym.h" 36 37/* 38 * uint8_t bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t bsh, 39 * bus_size_t offset); 40 */ 41ENTRY(bus_space_read_1) 42 movl 4(%esp), %eax 43 movl 8(%esp), %edx 44 addl 12(%esp), %edx 45 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 46 je 1f 47 movzbl (%edx), %eax 48 ret 491: 50 xorl %eax, %eax 51 inb %dx, %al 52 ret 53END(bus_space_read_1) 54 55/* 56 * uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t bsh, 57 * bus_size_t offset); 58 */ 59ENTRY(bus_space_read_2) 60 movl 4(%esp), %eax 61 movl 8(%esp), %edx 62 addl 12(%esp), %edx 63 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 64 je 1f 65 movzwl (%edx), %eax 66 ret 671: 68 xorl %eax, %eax 69 inw %dx, %ax 70 ret 71END(bus_space_read_2) 72 73/* 74 * uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t bsh, 75 * bus_size_t offset); 76 */ 77ENTRY(bus_space_read_4) 78 movl 4(%esp), %eax 79 movl 8(%esp), %edx 80 addl 12(%esp), %edx 81 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 82 je 1f 83 movl (%edx), %eax 84 ret 851: 86 inl %dx, %eax 87 ret 88END(bus_space_read_4) 89 90STRONG_ALIAS(bus_space_read_stream_1,bus_space_read_1) 91STRONG_ALIAS(bus_space_read_stream_2,bus_space_read_2) 92STRONG_ALIAS(bus_space_read_stream_4,bus_space_read_4) 93 94/* 95 * void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, 96 * bus_size_t offset, uint8_t value); 97 */ 98ENTRY(bus_space_write_1) 99 movl 4(%esp), %eax 100 movl 8(%esp), %edx 101 addl 12(%esp), %edx 102 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 103 movl 16(%esp), %eax 104 je 1f 105 movb %al, (%edx) 106 ret 1071: 108 outb %al, %dx 109 ret 110END(bus_space_write_1) 111 112/* 113 * void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, 114 * bus_size_t offset, uint16_t value); 115 */ 116ENTRY(bus_space_write_2) 117 movl 4(%esp), %eax 118 movl 8(%esp), %edx 119 addl 12(%esp), %edx 120 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 121 movl 16(%esp), %eax 122 je 1f 123 movw %ax, (%edx) 124 ret 1251: 126 outw %ax, %dx 127 ret 128END(bus_space_write_2) 129 130/* 131 * void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, 132 * bus_size_t offset, uint32_t value); 133 */ 134ENTRY(bus_space_write_4) 135 movl 4(%esp), %eax 136 movl 8(%esp), %edx 137 addl 12(%esp), %edx 138 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 139 movl 16(%esp), %eax 140 je 1f 141 movl %eax, (%edx) 142 ret 1431: 144 outl %eax, %dx 145 ret 146END(bus_space_write_4) 147 148STRONG_ALIAS(bus_space_write_stream_1,bus_space_write_1) 149STRONG_ALIAS(bus_space_write_stream_2,bus_space_write_2) 150STRONG_ALIAS(bus_space_write_stream_4,bus_space_write_4) 151 152/* 153 * void bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 154 * bus_size_t offset, uint8_t *addr, size_t count); 155 */ 156ENTRY(bus_space_read_multi_1) 157 pushl %edi 158 movl 8(%esp), %eax 159 movl 12(%esp), %edx 160 addl 16(%esp), %edx 161 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 162 movl 20(%esp), %edi 163 movl 24(%esp), %ecx 164 jne 1f 165 rep 166 insb %dx, %es:(%edi) 167 popl %edi 168 ret 169 .align 16 1701: 171 movb (%edx), %al 172 decl %ecx 173 movb %al, (%edi) 174 leal 1(%edi), %edi 175 jnz 1b 176 popl %edi 177 ret 178END(bus_space_read_multi_1) 179 180/* 181 * void bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 182 * bus_size_t offset, uint16_t *addr, size_t count); 183 */ 184ENTRY(bus_space_read_multi_2) 185 pushl %edi 186 movl 8(%esp), %eax 187 movl 12(%esp), %edx 188 addl 16(%esp), %edx 189 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 190 movl 20(%esp), %edi 191 movl 24(%esp), %ecx 192 jne 1f 193 rep 194 insw %dx, %es:(%edi) 195 popl %edi 196 ret 197 .align 16 1981: 199 movw (%edx), %ax 200 decl %ecx 201 movw %ax, (%edi) 202 leal 2(%edi), %edi 203 jnz 1b 204 popl %edi 205 ret 206END(bus_space_read_multi_2) 207 208/* 209 * void bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 210 * bus_size_t offset, uint32_t *addr, size_t count); 211 */ 212ENTRY(bus_space_read_multi_4) 213 pushl %edi 214 movl 8(%esp), %eax 215 movl 12(%esp), %edx 216 addl 16(%esp), %edx 217 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 218 movl 20(%esp), %edi 219 movl 24(%esp), %ecx 220 jne 1f 221 rep 222 insl %dx, %es:(%edi) 223 popl %edi 224 ret 225 .align 16 2261: 227 movl (%edx), %eax 228 decl %ecx 229 movl %eax, (%edi) 230 leal 4(%edi), %edi 231 jnz 1b 232 popl %edi 233 ret 234END(bus_space_read_multi_4) 235 236STRONG_ALIAS(bus_space_read_multi_stream_1,bus_space_read_multi_1) 237STRONG_ALIAS(bus_space_read_multi_stream_2,bus_space_read_multi_2) 238STRONG_ALIAS(bus_space_read_multi_stream_4,bus_space_read_multi_4) 239 240/* 241 * void bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 242 * bus_size_t offset, const uint8_t *addr, size_t count); 243 */ 244ENTRY(bus_space_write_multi_1) 245 pushl %esi 246 movl 8(%esp), %eax 247 movl 12(%esp), %edx 248 addl 16(%esp), %edx 249 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 250 movl 20(%esp), %esi 251 movl 24(%esp), %ecx 252 jne 1f 253 rep 254 outsb %ds:(%esi), %dx 255 popl %esi 256 ret 257 .align 16 2581: 259 movb (%esi), %al 260 decl %ecx 261 movb %al, (%edx) 262 leal 1(%esi), %esi 263 jnz 1b 264 popl %esi 265 ret 266END(bus_space_write_multi_1) 267 268/* 269 * void bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 270 * bus_size_t offset, const uint16_t *addr, size_t count); 271 */ 272ENTRY(bus_space_write_multi_2) 273 pushl %esi 274 movl 8(%esp), %eax 275 movl 12(%esp), %edx 276 addl 16(%esp), %edx 277 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 278 movl 20(%esp), %esi 279 movl 24(%esp), %ecx 280 jne 1f 281 rep 282 outsw %ds:(%esi), %dx 283 popl %esi 284 ret 285 .align 16 2861: 287 movw (%esi), %ax 288 decl %ecx 289 movw %ax, (%edx) 290 leal 2(%esi), %esi 291 jnz 1b 292 popl %esi 293 ret 294END(bus_space_write_multi_2) 295 296/* 297 * void bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 298 * bus_size_t offset, const uint32_t *addr, size_t count); 299 */ 300ENTRY(bus_space_write_multi_4) 301 pushl %esi 302 movl 8(%esp), %eax 303 movl 12(%esp), %edx 304 addl 16(%esp), %edx 305 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 306 movl 20(%esp), %esi 307 movl 24(%esp), %ecx 308 jne 1f 309 rep 310 outsl %ds:(%esi), %dx 311 popl %esi 312 ret 313 .align 16 3141: 315 movl (%esi), %eax 316 decl %ecx 317 movl %eax, (%edx) 318 leal 4(%esi), %esi 319 jnz 1b 320 popl %esi 321 ret 322END(bus_space_write_multi_4) 323 324STRONG_ALIAS(bus_space_write_multi_stream_1,bus_space_write_multi_1) 325STRONG_ALIAS(bus_space_write_multi_stream_2,bus_space_write_multi_2) 326STRONG_ALIAS(bus_space_write_multi_stream_4,bus_space_write_multi_4) 327 328/* 329 * void bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 330 * bus_size_t offset, uint8_t *addr, size_t count); 331 */ 332ENTRY(bus_space_read_region_1) 333 pushl %edi 334 movl 8(%esp), %eax 335 movl 12(%esp), %edx 336 addl 16(%esp), %edx 337 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 338 movl 20(%esp), %edi 339 movl 24(%esp), %ecx 340 je 2f 3411: 342 xchgl %edx, %esi 343 rep 344 movsb %ds:(%esi), %es:(%edi) 345 movl %edx, %esi 346 popl %edi 347 ret 3482: 349 inb %dx, %al 350 incl %edx 351 decl %ecx 352 movb %al, (%edi) 353 leal 1(%edi), %edi 354 jnz 2b 355 popl %edi 356 ret 357END(bus_space_read_region_1) 358 359/* 360 * void bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 361 * bus_size_t offset, uint16_t *addr, size_t count); 362 */ 363ENTRY(bus_space_read_region_2) 364 pushl %edi 365 movl 8(%esp), %eax 366 movl 12(%esp), %edx 367 addl 16(%esp), %edx 368 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 369 movl 20(%esp), %edi 370 movl 24(%esp), %ecx 371 je 2f 3721: 373 xchgl %edx, %esi 374 rep 375 movsw %ds:(%esi), %es:(%edi) 376 movl %edx, %esi 377 popl %edi 378 ret 3792: 380 inw %dx, %ax 381 addl $2, %edx 382 decl %ecx 383 movw %ax, (%edi) 384 leal 2(%edi), %edi 385 jnz 2b 386 popl %edi 387 ret 388END(bus_space_read_region_2) 389 390/* 391 * void bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 392 * bus_size_t offset, uint32_t *addr, size_t count); 393 */ 394ENTRY(bus_space_read_region_4) 395 pushl %edi 396 movl 8(%esp), %eax 397 movl 12(%esp), %edx 398 addl 16(%esp), %edx 399 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 400 movl 20(%esp), %edi 401 movl 24(%esp), %ecx 402 je 2f 4031: 404 xchgl %edx, %esi 405 rep 406 movsl %ds:(%esi), %es:(%edi) 407 movl %edx, %esi 408 popl %edi 409 ret 4102: 411 inl %dx, %eax 412 addl $4, %edx 413 decl %ecx 414 movl %eax, (%edi) 415 leal 4(%edi), %edi 416 jnz 2b 417 popl %edi 418 ret 419END(bus_space_read_region_4) 420 421STRONG_ALIAS(bus_space_read_region_stream_1,bus_space_read_region_1) 422STRONG_ALIAS(bus_space_read_region_stream_2,bus_space_read_region_2) 423STRONG_ALIAS(bus_space_read_region_stream_4,bus_space_read_region_4) 424 425/* 426 * void bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 427 * bus_size_t offset, const uint8_t *addr, size_t count); 428 */ 429ENTRY(bus_space_write_region_1) 430 pushl %esi 431 movl 8(%esp), %eax 432 movl 12(%esp), %edx 433 addl 16(%esp), %edx 434 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 435 movl 20(%esp), %esi 436 movl 24(%esp), %ecx 437 je 2f 4381: 439 xchgl %edx, %edi 440 rep 441 movsb %ds:(%esi), %es:(%edi) 442 movl %edx, %edi 443 popl %esi 444 ret 4452: 446 movb (%esi), %al 447 incl %esi 448 decl %ecx 449 outb %al, %dx 450 leal 1(%edx), %edx 451 jnz 2b 452 popl %esi 453 ret 454END(bus_space_write_region_1) 455 456/* 457 * void bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 458 * bus_size_t offset, const uint16_t *addr, size_t count); 459 */ 460ENTRY(bus_space_write_region_2) 461 pushl %esi 462 movl 8(%esp), %eax 463 movl 12(%esp), %edx 464 addl 16(%esp), %edx 465 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 466 movl 20(%esp), %esi 467 movl 24(%esp), %ecx 468 je 2f 4691: 470 xchgl %edx, %edi 471 rep 472 movsw %ds:(%esi), %es:(%edi) 473 movl %edx, %edi 474 popl %esi 475 ret 4762: 477 movw (%esi), %ax 478 addl $2, %esi 479 decl %ecx 480 outw %ax, %dx 481 leal 2(%edx), %edx 482 jnz 2b 483 popl %esi 484 ret 485END(bus_space_write_region_2) 486 487/* 488 * void bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 489 * bus_size_t offset, const uint32_t *addr, size_t count); 490 */ 491ENTRY(bus_space_write_region_4) 492 pushl %esi 493 movl 8(%esp), %eax 494 movl 12(%esp), %edx 495 addl 16(%esp), %edx 496 cmpl $X86_BUS_SPACE_IO, BST_TYPE(%eax) 497 movl 20(%esp), %esi 498 movl 24(%esp), %ecx 499 je 2f 5001: 501 xchgl %edx, %edi 502 rep 503 movsl %ds:(%esi), %es:(%edi) 504 movl %edx, %edi 505 popl %esi 506 ret 5072: 508 movl (%esi), %eax 509 addl $4, %esi 510 decl %ecx 511 outl %eax, %dx 512 leal 4(%edx), %edx 513 jnz 2b 514 popl %esi 515 ret 516END(bus_space_write_region_4) 517 518STRONG_ALIAS(bus_space_write_region_stream_1,bus_space_write_region_1) 519STRONG_ALIAS(bus_space_write_region_stream_2,bus_space_write_region_2) 520STRONG_ALIAS(bus_space_write_region_stream_4,bus_space_write_region_4) 521