1 /* 2 * Copyright (c) 2006 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * 22 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 23 * contributors may be used to endorse or promote products derived from this 24 * software without specific prior written permission. 25 */ 26 27 /* 28 * Cimarron hardware access macros. 29 */ 30 31 #ifndef _cim_defs_h 32 #define _cim_defs_h 33 34 /*-----------------------------------------*/ 35 /* MEMORY ACCESS MACROS */ 36 /*-----------------------------------------*/ 37 38 #ifndef CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS 39 40 #define READ_GP32(offset) \ 41 (*(volatile unsigned long *)(cim_gp_ptr + (offset))) 42 43 #define READ_REG32(offset) \ 44 (*(volatile unsigned long *)(cim_vg_ptr + (offset))) 45 46 #define READ_FB32(offset) \ 47 (*(volatile unsigned long *)(cim_fb_ptr + (offset))) 48 49 #define WRITE_GP32(offset, value) \ 50 (*(volatile unsigned long *)(cim_gp_ptr + (offset))) = (value) 51 52 #define WRITE_REG32(offset, value) \ 53 (*(volatile unsigned long *)(cim_vg_ptr + (offset))) = (value) 54 55 #define WRITE_COMMAND32(offset, value) \ 56 (*(unsigned long *)(cim_cmd_ptr + (offset))) = (value) 57 58 #define WRITE_COMMAND8(offset, value) \ 59 (*(unsigned char *)(cim_cmd_ptr + (offset))) = (value) 60 61 #define WRITE_FB32(offset, value) \ 62 (*(unsigned long *)(cim_fb_ptr + (offset))) = (value) 63 64 #define READ_VID32(offset) \ 65 (*(volatile unsigned long *)(cim_vid_ptr + (offset))) 66 67 #define WRITE_VID32(offset, value) \ 68 (*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value) 69 70 #define READ_VIP32(offset) \ 71 (*(volatile unsigned long *)(cim_vip_ptr + (offset))) 72 73 #define WRITE_VIP32(offset, value) \ 74 (*(volatile unsigned long *)(cim_vip_ptr + (offset))) = (value) 75 76 #define READ_VOP32(offset) \ 77 (*(volatile unsigned long *)(cim_vid_ptr + (offset))) 78 79 #define WRITE_VOP32(offset, value) \ 80 (*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value) 81 82 #endif 83 84 /*-----------------------------------------*/ 85 /* GP POLLING MACROS */ 86 /*-----------------------------------------*/ 87 88 #define GP3_WAIT_WRAP(variable) \ 89 while(((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) || \ 90 (variable <= (gp3_cmd_top + GP3_BLT_COMMAND_SIZE + GP3_BLT_COMMAND_SIZE + 96))) 91 92 #define GP3_WAIT_PRIMITIVE(variable) \ 93 while (((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) && \ 94 (variable <= (gp3_cmd_next + 96))) 95 96 #define GP3_WAIT_BUSY \ 97 while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_BUSY) 98 99 #define GP3_WAIT_PENDING \ 100 while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_PENDING) 101 102 /*-----------------------------------------------------------------*/ 103 /* MSR MACROS */ 104 /* These macros facilitate interaction with the model specific */ 105 /* registers in GeodeLX. There are two included methods, direct */ 106 /* access using the rdmsr and wrmsr opcodes and an indirect method */ 107 /* using VSAII. */ 108 /*-----------------------------------------------------------------*/ 109 110 #ifdef CIMARRON_INCLUDE_MSR_MACROS 111 112 #if CIMARRON_MSR_DIRECT_ASM 113 114 /*----------------------------------------------------------------- 115 * MSR_READ 116 * Read the contents of a 64 bit MSR into a data structure 117 *-----------------------------------------------------------------*/ 118 119 #define MSR_READ(msr_reg, device_add, data64_ptr) \ 120 { \ 121 unsigned long msr_add = (unsigned long)(msr_reg) | \ 122 (unsigned long)(device_add); \ 123 unsigned long data_high, data_low; \ 124 _asm { mov ecx, msr_add } \ 125 _asm { rdmsr } \ 126 _asm { mov data_high, edx } \ 127 _asm { mov data_low, eax } \ 128 \ 129 ((Q_WORD *)(data64_ptr))->high = data_high; \ 130 ((Q_WORD *)(data64_ptr))->low = data_low; \ 131 } 132 133 /*----------------------------------------------------------------- 134 * MSR_WRITE 135 * Write the contents of a 64 bit data structure to a MSR. 136 *-----------------------------------------------------------------*/ 137 138 #define MSR_WRITE(msr_reg, device_add, data64_ptr) \ 139 { \ 140 unsigned long msr_add = (unsigned long)(msr_reg) | \ 141 (unsigned long)(device_add); \ 142 unsigned long data_high, data_low; \ 143 \ 144 data_high = ((Q_WORD *)(data64_ptr))->high; \ 145 data_low = ((Q_WORD *)(data64_ptr))->low; \ 146 \ 147 _asm { mov ecx, msr_add } \ 148 _asm { mov edx, data_high } \ 149 _asm { mov eax, data_low } \ 150 _asm { wrmsr } \ 151 } 152 153 #elif CIMARRON_MSR_VSA_IO 154 155 /*----------------------------------------------------------------- 156 * MSR_READ 157 * Read the contents of a 64 bit MSR into a data structure 158 *-----------------------------------------------------------------*/ 159 160 #define MSR_READ(msr_reg, device_add, data64_ptr) \ 161 { \ 162 unsigned long msr_add = (unsigned long)(msr_reg) | \ 163 (unsigned long)(device_add); \ 164 unsigned long data_high, data_low; \ 165 \ 166 _asm { mov dx, 0x0AC1C } \ 167 _asm { mov eax, 0x0FC530007 } \ 168 _asm { out dx, eax } \ 169 \ 170 _asm { add dl, 2 } \ 171 _asm { mov ecx, msr_add } \ 172 _asm { in ax, dx } \ 173 _asm { mov data_high, edx } \ 174 _asm { mov data_low, eax } \ 175 \ 176 ((Q_WORD *)(data64_ptr))->high = data_high; \ 177 ((Q_WORD *)(data64_ptr))->low = data_low; \ 178 } 179 180 /*----------------------------------------------------------------- 181 * MSR_WRITE 182 * Write the contents of a 64 bit data structure to a MSR. 183 *-----------------------------------------------------------------*/ 184 185 #define MSR_WRITE(msr_reg, device_add, data64_ptr) \ 186 { \ 187 unsigned long msr_add = (unsigned long)(msr_reg) | \ 188 (unsigned long)(device_add); \ 189 unsigned long data_high, data_low; \ 190 \ 191 data_high = ((Q_WORD *)(data64_ptr))->high; \ 192 data_low = ((Q_WORD *)(data64_ptr))->low; \ 193 \ 194 _asm { mov dx, 0x0AC1C } \ 195 _asm { mov eax, 0x0FC530007 } \ 196 _asm { out dx, eax } \ 197 \ 198 _asm { add dl, 2 } \ 199 _asm { mov ecx, msr_add } \ 200 _asm { mov ebx, data_high } \ 201 _asm { mov eax, data_low } \ 202 \ 203 _asm { mov esi, 0 } \ 204 _asm { mov edi, 0 } \ 205 _asm { out dx, ax } \ 206 } 207 208 #elif CIMARRON_MSR_ABSTRACTED_ASM 209 210 /*----------------------------------------------------------------- 211 * MSR_READ 212 * Read the contents of a 64 bit MSR into a data structure 213 *-----------------------------------------------------------------*/ 214 215 #define MSR_READ(msr,adr,val) \ 216 __asm__ __volatile__( \ 217 " mov $0x0AC1C, %%edx\n" \ 218 " mov $0xFC530007, %%eax\n" \ 219 " out %%eax,%%dx\n" \ 220 " add $2,%%dl\n" \ 221 " in %%dx, %%ax" \ 222 : "=a" ((val)->low), "=d" ((val)->high) \ 223 : "c" (msr | adr)) 224 225 /*----------------------------------------------------------------- 226 * MSR_WRITE 227 * Write the contents of a 64 bit data structure to a MSR. 228 *-----------------------------------------------------------------*/ 229 230 #define MSR_WRITE(msr,adr,val) \ 231 { int d0, d1, d2, d3; \ 232 __asm__ __volatile__( \ 233 " push %%ebx\n" \ 234 " mov $0x0AC1C, %%edx\n" \ 235 " mov $0xFC530007, %%eax\n" \ 236 " out %%eax,%%dx\n" \ 237 " add $2,%%dl\n" \ 238 " mov %4, %3\n" \ 239 " mov 0(%5), %%ebx\n" \ 240 " mov 4(%5), %0\n" \ 241 " xor %2, %2\n" \ 242 " xor %1, %1\n" \ 243 " out %%ax, %%dx\n" \ 244 " pop %%ebx\n" \ 245 : "=a" (d0), "=&D" (d1), "=&S" (d2), "=c" (d3) \ 246 : "1" (msr | adr), "2" (val)); \ 247 } 248 249 #elif CIMARRON_MSR_KERNEL_ROUTINE 250 251 #include "asm/msr.h" 252 253 /*----------------------------------------------------------------- 254 * MSR_READ 255 * Read the contents of a 64 bit MSR into a data structure 256 *-----------------------------------------------------------------*/ 257 258 #define MSR_READ(msr_reg, device_add, data64_ptr) \ 259 { \ 260 unsigned long addr, val1, val2; \ 261 \ 262 addr = device_add | msr_reg; \ 263 rdmsr (addr, val1, val2); \ 264 \ 265 ((Q_WORD *)(data64_ptr))->high = val2; \ 266 ((Q_WORD *)(data64_ptr))->low = val1; \ 267 } 268 269 /*----------------------------------------------------------------- 270 * MSR_WRITE 271 * Read the contents of a 64 bit data structure to a MSR. 272 *-----------------------------------------------------------------*/ 273 274 #define MSR_WRITE(msr_reg, device_add, data64_ptr) \ 275 { \ 276 unsigned long addr, val1, val2; \ 277 \ 278 val2 = ((Q_WORD *)(data64_ptr))->high; \ 279 val1 = ((Q_WORD *)(data64_ptr))->low; \ 280 \ 281 addr = (device_add & 0xFFFF0000) | (unsigned long)msr_reg; \ 282 wrmsr(addr, val1, val2); \ 283 } 284 285 #elif CIMARRON_MSR_HOOKS 286 287 #define MSR_READ(msr_reg, device_add, data64_ptr) \ 288 { \ 289 unsigned long addr, val1, val2; \ 290 \ 291 addr = device_add | msr_reg; \ 292 if (cim_rdmsr) { \ 293 cim_rdmsr (addr, &val1, &val2); \ 294 \ 295 ((Q_WORD *)(data64_ptr))->high = val2; \ 296 ((Q_WORD *)(data64_ptr))->low = val1; \ 297 } \ 298 } 299 300 #define MSR_WRITE(msr_reg, device_add, data64_ptr) \ 301 { \ 302 unsigned long addr, val1, val2; \ 303 \ 304 val2 = ((Q_WORD *)(data64_ptr))->high; \ 305 val1 = ((Q_WORD *)(data64_ptr))->low; \ 306 \ 307 addr = (device_add & 0xFFFF0000) | (unsigned long)msr_reg; \ 308 if (cim_wrmsr) \ 309 cim_wrmsr(addr, val1, val2); \ 310 } 311 #endif 312 313 #endif /* #ifdef CIMARRON_INCLUDE_MSR_MACROS */ 314 315 /*-----------------------------------------------------------------*/ 316 /* STRING MACROS */ 317 /* These macros are included to facilitate the optimization of */ 318 /* routines that write or copy large amounts of data. Two versions */ 319 /* of these macros are included. One is intended for operating */ 320 /* systems that allow the use of inline assembly, while the other */ 321 /* is a pure C implementation for stricter operating systems. */ 322 /*-----------------------------------------------------------------*/ 323 324 #ifdef CIMARRON_INCLUDE_STRING_MACROS 325 326 #if CIMARRON_OPTIMIZE_ASSEMBLY 327 328 /*----------------------------------------------------------------- 329 * WRITE_COMMAND_STRING32 330 * Write a series of DWORDs to the current command buffer offset 331 *-----------------------------------------------------------------*/ 332 333 #define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \ 334 { \ 335 _asm { cld } \ 336 _asm { mov edi, cim_cmd_ptr } \ 337 _asm { add edi, offset } \ 338 _asm { mov esi, dataptr } \ 339 _asm { add esi, dataoffset } \ 340 _asm { mov ecx, dword_count } \ 341 _asm { rep movsd } \ 342 } 343 344 /*----------------------------------------------------------------- 345 * WRITE_FB_STRING32 346 * Write a series of DWORDS to video memory. 347 *-----------------------------------------------------------------*/ 348 349 #define WRITE_FB_STRING32(offset, dataptr, dword_count) \ 350 { \ 351 unsigned long temp = (unsigned long)(dataptr); \ 352 _asm { cld } \ 353 _asm { mov edi, cim_fb_ptr } \ 354 _asm { add edi, offset } \ 355 _asm { mov esi, temp } \ 356 _asm { mov ecx, dword_count } \ 357 _asm { rep movsd } \ 358 } 359 360 /*----------------------------------------------------------------- 361 * WRITE_FB_CONSTANT 362 * Write a constant DWORD to multiple video memory addresses 363 *-----------------------------------------------------------------*/ 364 365 #define WRITE_FB_CONSTANT(offset, value, dword_count) \ 366 { \ 367 unsigned long outptr = (unsigned long)cim_fb_ptr + offset; \ 368 unsigned long dwords = dword_count; \ 369 _asm { cld } \ 370 _asm { mov edi, outptr } \ 371 _asm { mov eax, value } \ 372 _asm { mov ecx, dwords } \ 373 _asm { rep stosd } \ 374 } 375 376 /*----------------------------------------------------------------- 377 * WRITE_HOST_SOURCE_STRING32 378 * Write a series of DWORDs to the GP host source register 379 *-----------------------------------------------------------------*/ 380 381 #define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \ 382 { \ 383 _asm { cld } \ 384 _asm { mov edi, cim_gp_ptr } \ 385 _asm { add edi, GP3_HST_SRC_RANGE } \ 386 _asm { mov esi, dataptr } \ 387 _asm { add esi, dataoffset } \ 388 _asm { mov ecx, dword_count } \ 389 _asm { rep movsd } \ 390 } 391 392 #elif CIMARRON_OPTIMIZE_FORLOOP 393 394 /*----------------------------------------------------------------- 395 * WRITE_COMMAND_STRING32 396 * Write a series of DWORDs to the current command buffer offset 397 *-----------------------------------------------------------------*/ 398 399 #define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \ 400 { \ 401 unsigned long i; \ 402 unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \ 403 unsigned long byte_off = 0; \ 404 for (i = 0; i < dword_count; i++, byte_off += 4) \ 405 WRITE_COMMAND32 ((offset) + byte_off, \ 406 *((unsigned long *)(tempdata + byte_off))); \ 407 } 408 409 /*----------------------------------------------------------------- 410 * WRITE_FB_STRING32 411 * Write a series of DWORDS to video memory. 412 *-----------------------------------------------------------------*/ 413 414 #define WRITE_FB_STRING32(offset, dataptr, dword_count) \ 415 { \ 416 unsigned long i; \ 417 unsigned long tempdata = (unsigned long)dataptr; \ 418 unsigned long byte_off = 0; \ 419 for (i = 0; i < dword_count; i++, byte_off += 4) \ 420 WRITE_FB32 ((offset) + byte_off, \ 421 *((unsigned long *)(tempdata + byte_off))); \ 422 } 423 424 /*----------------------------------------------------------------- 425 * WRITE_FB_CONSTANT 426 * Write a constant DWORD to multiple video memory addresses 427 *-----------------------------------------------------------------*/ 428 429 #define WRITE_FB_CONSTANT(offset, value, dword_count) \ 430 { \ 431 unsigned long i; \ 432 unsigned long tempoffset = offset; \ 433 for (i = 0; i < dword_count; i++, tempoffset += 4) \ 434 WRITE_FB32 (tempoffset, value); \ 435 } 436 437 /*----------------------------------------------------------------- 438 * WRITE_HOST_SOURCE_STRING32 439 * Write a series of DWORDs to the GP host source register 440 *-----------------------------------------------------------------*/ 441 442 #define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \ 443 { \ 444 unsigned long i; \ 445 unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \ 446 unsigned long byte_off = 0; \ 447 for (i = 0; i < dword_count; i++, byte_off += 4) \ 448 WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, \ 449 *((unsigned long *)(tempdata + byte_off))); \ 450 } 451 452 #elif CIMARRON_OPTIMIZE_ABSTRACTED_ASM 453 454 #define move_dw(d,s,n) \ 455 __asm__ __volatile__( \ 456 " rep\n" \ 457 " movsl\n" \ 458 : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ 459 : "0" (n), "1" ((const char *)s), "2" ((char *)d) \ 460 : "memory") 461 462 /*----------------------------------------------------------------- 463 * WRITE_COMMAND_STRING32 464 * Write a series of DWORDs to the current command buffer offset 465 *-----------------------------------------------------------------*/ 466 467 #define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \ 468 { \ 469 int d0, d1, d2; \ 470 move_dw (cim_cmd_ptr+ ((unsigned long)(offset)), \ 471 ((unsigned long)(dataptr)+(dataoffset)), \ 472 dword_count); \ 473 } 474 475 /*----------------------------------------------------------------- 476 * WRITE_FB_STRING32 477 * Write a series of DWORDS to video memory. 478 *-----------------------------------------------------------------*/ 479 480 #define WRITE_FB_STRING32(offset, dataptr, dword_count) \ 481 { \ 482 unsigned long i; \ 483 unsigned long tempdata = (unsigned long)dataptr; \ 484 unsigned long byte_off = 0; \ 485 for (i = 0; i < dword_count; i++, byte_off += 4) \ 486 WRITE_FB32 ((offset) + byte_off, \ 487 *((unsigned long *)(tempdata + byte_off))); \ 488 } 489 490 /*----------------------------------------------------------------- 491 * WRITE_FB_CONSTANT 492 * Write a constant DWORD to multiple video memory addresses 493 *-----------------------------------------------------------------*/ 494 495 #define WRITE_FB_CONSTANT(offset, value, dword_count) \ 496 { \ 497 unsigned long i; \ 498 unsigned long tempoffset = offset; \ 499 for (i = 0; i < dword_count; i++, tempoffset += 4) \ 500 WRITE_FB32 (tempoffset, value); \ 501 } 502 503 /*----------------------------------------------------------------- 504 * WRITE_HOST_SOURCE_STRING32 505 * Write a series of DWORDs to the GP host source register 506 *-----------------------------------------------------------------*/ 507 508 #define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \ 509 { \ 510 unsigned long i; \ 511 unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \ 512 unsigned long byte_off = 0; \ 513 for (i = 0; i < dword_count; i++, byte_off += 4) \ 514 WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, \ 515 *((unsigned long *)(tempdata + byte_off))); \ 516 } 517 518 #endif 519 520 #endif /* #ifdef CIMARRON_INCLUDE_STRING_MACROS */ 521 522 /*----------------------------------------------------------------- 523 * WRITE_COMMAND_STRING8 524 * Write a series of bytes to the current command buffer offset 525 *-----------------------------------------------------------------*/ 526 527 #define WRITE_COMMAND_STRING8(offset, dataptr, dataoffset, byte_count) \ 528 { \ 529 unsigned long i; \ 530 unsigned long array = (unsigned long)dataptr + (dataoffset); \ 531 for (i = 0; i < byte_count; i++) \ 532 WRITE_COMMAND8 ((offset) + i, *((unsigned char *)(array + i))); \ 533 } 534 535 /*----------------------------------------------------------------- 536 * WRITE_HOST_SOURCE_STRING8 537 * Write a series of bytes to the host source register 538 *-----------------------------------------------------------------*/ 539 540 #define WRITE_HOST_SOURCE_STRING8(dataptr, dataoffset, byte_count) \ 541 { \ 542 unsigned long temp1 = (unsigned long)dataptr + (dataoffset); \ 543 unsigned long temp2 = 0; \ 544 unsigned long shift = 0; \ 545 unsigned long counter; \ 546 if (byte_count) \ 547 { \ 548 for (counter = 0; counter < byte_count; counter++) \ 549 { \ 550 temp2 |= ((unsigned long)(*((unsigned char *) \ 551 (temp1 + counter)))) << shift; \ 552 shift += 8; \ 553 } \ 554 WRITE_GP32 (GP3_HST_SRC, temp2); \ 555 } \ 556 } 557 558 /*-----------------------------------------*/ 559 /* CUSTOM STRING MACROS */ 560 /*-----------------------------------------*/ 561 562 #ifndef CIMARRON_EXCLUDE_CUSTOM_MACROS 563 564 #define WRITE_CUSTOM_COMMAND_STRING32 WRITE_COMMAND_STRING32 565 #define WRITE_CUSTOM_COMMAND_STRING8 WRITE_COMMAND_STRING8 566 567 #endif 568 569 /*-----------------------------------------*/ 570 /* IO ACCESS MACROS */ 571 /*-----------------------------------------*/ 572 573 #ifdef CIMARRON_INCLUDE_IO_MACROS 574 575 #if CIMARRON_IO_DIRECT_ACCESS 576 577 /*------------------------------------------- 578 * OUTD 579 * Writes one DWORD to a single I/O address. 580 *-------------------------------------------*/ 581 582 #define OUTD(port, data) cim_outd(port, data) 583 void 584 cim_outd(unsigned short port, unsigned long data) 585 { 586 _asm { 587 pushf mov eax, data mov dx, port out dx, eax popf}} 588 /*------------------------------------------- 589 * IND 590 * Reads one DWORD from a single I/O address. 591 *-------------------------------------------*/ 592 #define IND(port) cim_ind(port) 593 unsigned long 594 cim_ind(unsigned short port) 595 { 596 unsigned long data; 597 598 _asm { 599 pushf mov dx, port in eax, dx mov data, eax popf} return data; 600 } 601 602 /*------------------------------------------- 603 * OUTW 604 * Writes one WORD to a single I/O address. 605 *-------------------------------------------*/ 606 607 #define OUTW(port, data) cim_outw(port, data) 608 void 609 cim_outw(unsigned short port, unsigned short data) 610 { 611 _asm { 612 pushf mov ax, data mov dx, port out dx, ax popf}} 613 /*------------------------------------------- 614 * INW 615 * Reads one WORD from a single I/O address. 616 *-------------------------------------------*/ 617 #define INW(port) cim_inw(port) 618 unsigned short 619 cim_inw(unsigned short port) 620 { 621 unsigned short data; 622 623 _asm { 624 pushf mov dx, port in ax, dx mov data, ax popf} return data; 625 } 626 627 /*------------------------------------------- 628 * OUTB 629 * Writes one BYTE to a single I/O address. 630 *-------------------------------------------*/ 631 632 #define OUTB(port, data) cim_outb(port, data) 633 void 634 cim_outb(unsigned short port, unsigned char data) 635 { 636 _asm { 637 pushf mov al, data mov dx, port out dx, al popf}} 638 /*------------------------------------------- 639 * INB 640 * Reads one BYTE from a single I/O address. 641 *-------------------------------------------*/ 642 #define INB(port) cim_inb(port) 643 unsigned char 644 cim_inb(unsigned short port) 645 { 646 unsigned char data; 647 648 _asm { 649 pushf mov dx, port in al, dx mov data, al popf} return data; 650 } 651 652 #elif CIMARRON_IO_ABSTRACTED_ASM 653 654 /*------------------------------------------- 655 * OUTD 656 * Writes one DWORD to a single I/O address. 657 *-------------------------------------------*/ 658 659 #define OUTD(port, data) cim_outd(port, data) 660 void cim_outd(unsigned short port, unsigned long data); 661 void 662 cim_outd(unsigned short port, unsigned long data) 663 { 664 __asm__ __volatile__("outl %0,%w1"::"a"(data), "Nd"(port)); 665 } 666 667 /*------------------------------------------- 668 * IND 669 * Reads one DWORD from a single I/O address. 670 *-------------------------------------------*/ 671 672 #define IND(port) cim_ind(port) 673 unsigned long cim_ind(unsigned short port); 674 unsigned long 675 cim_ind(unsigned short port) 676 { 677 unsigned long value; 678 __asm__ __volatile__("inl %w1,%0":"=a"(value):"Nd"(port)); 679 680 return value; 681 } 682 683 /*------------------------------------------- 684 * OUTW 685 * Writes one WORD to a single I/O address. 686 *-------------------------------------------*/ 687 688 #define OUTW(port, data) cim_outw(port, data) 689 void cim_outw(unsigned short port, unsigned short data); 690 void 691 cim_outw(unsigned short port, unsigned short data) 692 { 693 __asm__ volatile ("out %0,%1"::"a" (data), "d"(port)); 694 } 695 696 /*------------------------------------------- 697 * INW 698 * Reads one WORD from a single I/O address. 699 *-------------------------------------------*/ 700 701 #define INW(port) cim_inw(port) 702 unsigned short cim_inw(unsigned short port); 703 unsigned short 704 cim_inw(unsigned short port) 705 { 706 unsigned short value; 707 __asm__ volatile ("in %1,%0":"=a" (value):"d"(port)); 708 709 return value; 710 } 711 712 /*------------------------------------------- 713 * INB 714 * Reads one BYTE from a single I/O address. 715 *-------------------------------------------*/ 716 717 #define INB(port) cim_inb(port) 718 unsigned char cim_inb(unsigned short port); 719 unsigned char 720 cim_inb(unsigned short port) 721 { 722 unsigned char value; 723 __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port)); 724 725 return value; 726 } 727 728 /*------------------------------------------- 729 * OUTB 730 * Writes one BYTE to a single I/O address. 731 *-------------------------------------------*/ 732 733 #define OUTB(port) cim_outb(port) 734 void cim_outb(unsigned short port, unsigned char data); 735 void 736 cim_outb(unsigned short port, unsigned char data) 737 { 738 __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port)); 739 } 740 741 #endif 742 743 #endif /* CIMARRON_INCLUDE_IO_MACROS */ 744 745 extern void (*cim_rdmsr) (unsigned long, unsigned long *, unsigned long *); 746 extern void (*cim_wrmsr) (unsigned long, unsigned long, unsigned long); 747 748 #endif 749