Home | History | Annotate | Line # | Download | only in cim
      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