Annotation of ntddk/src/video/inc/ioaccess.h, revision 1.1.1.1

1.1       root        1: /*++ BUILD Version: 0002    // Increment this if a change has global effects
                      2: 
                      3: Copyright (c) 1989-91  Microsoft Corporation
                      4: Copyright (c) 1992 Digital Equipment Corporation
                      5: 
                      6: Module Name:
                      7: 
                      8:     ioaccess.h
                      9: 
                     10: Abstract:
                     11: 
                     12:     Definitions of function prototypes for accessing I/O ports and
                     13:     memory on I/O adapters from user mode programs.
                     14: 
                     15:     Cloned from parts of nti386.h.
                     16: 
                     17: Author:
                     18: 
                     19: 
                     20: --*/
                     21: 
                     22: #ifndef _IOACCESS_
                     23: #define _IOACCESS_
                     24: 
                     25: 
                     26: //  Only define these prototypes if they're not already defined
                     27: 
                     28: #if defined (i386)
                     29: 
                     30: //
                     31: // I/O space read and write macros.
                     32: //
                     33: //  These have to be actual functions on the 386, because we need
                     34: //  to use assembler, but cannot return a value if we inline it.
                     35: //
                     36: //  The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space.
                     37: //  (Use x86 move instructions, with LOCK prefix to force correct behavior
                     38: //   w.r.t. caches and write buffers.)
                     39: //
                     40: //  The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space.
                     41: //  (Use x86 in/out instructions.)
                     42: //
                     43: 
                     44: #define READ_REGISTER_UCHAR(Register) (*(PUCHAR)(Register))
                     45: 
                     46: #define READ_REGISTER_USHORT(Register) (*(PUSHORT)(Register))
                     47: 
                     48: #define READ_REGISTER_ULONG(Register) (*(PULONG)(Register))
                     49: 
                     50: #define WRITE_REGISTER_UCHAR(Register, Value) (*(volatile UCHAR *)(Register) = (Value))
                     51: 
                     52: #define WRITE_REGISTER_USHORT(Register, Value) (*(volatile USHORT *)(Register) = (Value))
                     53: 
                     54: #define WRITE_REGISTER_ULONG(Register, Value) (*(volatile ULONG *)(Register) = (Value))
                     55: 
                     56: #define READ_PORT_UCHAR(Port) inp (Port)
                     57: 
                     58: #define READ_PORT_USHORT(Port) inpw (Port)
                     59: 
                     60: #define WRITE_PORT_UCHAR(Port, Value) outp ((Port), (Value))
                     61: 
                     62: #define WRITE_PORT_USHORT(Port, Value) outpw ((Port), (Value))
                     63: 
                     64: #define MEMORY_BARRIER()
                     65: 
                     66: #endif        // defined(i386)
                     67: 
                     68: 
                     69: #if defined (ALPHA)
                     70: //
                     71: // I/O space read and write macros.
                     72: //
                     73: //  The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space.
                     74: //  (Use simple C macros. The caller is responsible for inserting memory 
                     75: //  barriers, as appropriate.) 
                     76: //
                     77: //  The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space.
                     78: //  (Use subroutine calls, since these are used less frequently than the
                     79: //  register routines, and require more context.)
                     80: //
                     81: 
                     82: 
                     83: /*++
                     84: 
                     85: VOID
                     86: MEMORY_BARRIER(
                     87:                VOID
                     88:               )
                     89: 
                     90: Routine Description:
                     91: 
                     92:     Execute an Alpha AXP MB instruction, to force pending writes
                     93:     out to the bus.
                     94: 
                     95: Arguments:
                     96: 
                     97:     None.
                     98: 
                     99: Return Value:
                    100: 
                    101:     None.
                    102: 
                    103: --*/
                    104: 
                    105: #if defined(_MSC_VER)
                    106: 
                    107: #define MEMORY_BARRIER()  __MB()
                    108: 
                    109: #else
                    110: #if defined(ACCASM) && !defined(__CPLUSPLUS)
                    111: 
                    112: long asm(const char *,...);
                    113: #pragma intrinsic(asm)
                    114: 
                    115: //
                    116: //  ACC has a bug whereby an "asm" directive that occurs in a 
                    117: //  routine *before* any function calls, will bugcheck the
                    118: //  compiler.
                    119: //  Remove the following symbol definition when this is fixed.
                    120: //
                    121: 
                    122: #define ACC_ASM_BUG 1
                    123: 
                    124: #define MEMORY_BARRIER()        asm("mb")
                    125: 
                    126: #endif        // ACCASM
                    127: #endif // _MSC_VER
                    128: 
                    129: 
                    130: //  Alpha AXP Platform support
                    131: //
                    132: //  Note that these macros are cloned from ...\ntos\hal\alpha.jxiouser.c.
                    133: //
                    134: //  All these macros require that the calling argument is a QVA, such
                    135: //  as would be returned by HalCreateQva - this should
                    136: //  have QVA_ENABLE set.  They assume the QVA represents an I/O bus address,
                    137: //  and do conditionally select QVA-to-VA decoding based on this.
                    138: //
                    139: //  Note that the argument is declared as PUCHAR or PUSHORT or
                    140: //  whatever, even though it really is a QUASI_VIRTUAL_ADDRESS.  This
                    141: //  is for driver compatibility:  all the drivers out there get a
                    142: //  PVOID from ZwMapViewOfSection, then cast it to PU* before calling these
                    143: //  routines.  If we insisted on declaring them correctly, we would
                    144: //  have to change all the drivers, which is what we are trying to avoid.
                    145: //
                    146: //  Lane shifting: Alpha AXP PC's will not do lane shifting in sparse 
                    147: //  I/O bus address spaces That means that for access shorter than a 
                    148: //  longword, the data will NOT show up in the lowest bit position, 
                    149: //  but will be in the byte/word that it would have started in.  
                    150: //  For longwords, the value will show up on the data path correctly.  
                    151: //  For, say, the 3rd byte in a word, a longword would be returned, 
                    152: //  and bytes 0, 1 and 3 would be garbage, and the value in byte 2 
                    153: //  would be the one you wanted.  The same applies for writing: a 
                    154: //  longword will always be sent out onto the bus, and we must move 
                    155: //  the valid data byte into the correct position, and set the byte 
                    156: //  enables to say which byte to use.  Note that what you cannot do is 
                    157: //  leave the byte in the lowest position, and set the byte enable 
                    158: //  to the lowest byte, because this would generate an unaligned 
                    159: //  longword access, which the Alpha AXP chip cannot handle.
                    160: //
                    161: //  So, for bytes, the access must be an aligned longword, with byte
                    162: //  enables set to indicate which byte to get/set, and the byte moved
                    163: //  to/from the desired position within the longword.  Similarly for
                    164: //  shorts.  Tribytes are not supported.
                    165: //
                    166: 
                    167: //
                    168: // I/O access values
                    169: //
                    170: 
                    171: // QVA Encoding:
                    172: //   Bits (31:29) are used to tag a QVA 
                    173: //   Bits (28:27) in QVA used for address space encoding
                    174: 
                    175: #define QVA_ENABLE         0xa0000000
                    176: #define QVA_ADDRESS_SPACE  0x18000000
                    177: #define QVA_SELECTORS      0xb8000000        // (QVA_ENABLE | QVA_ADDRESS_SPACE)
                    178: 
                    179: // Jensen-style sparse address space definition (JENSEN_QVA)
                    180: // Used for EISA bus I/O accesses.
                    181: 
                    182: #define JENSEN_QVA       0xb0000000          // (QVA_ENABLE | 0x10000000)
                    183: 
                    184: #define EISA_BIT_SHIFT   0x07                // Bits to shift address
                    185: 
                    186: #define EISA_BYTE_LEN    0x00                // Byte length
                    187: #define EISA_WORD_LEN    0x20                // Word length
                    188: #define EISA_LONG_LEN    0x60                // LONGWORD length
                    189: 
                    190: // Morgan-style sparse address space definition (OTHER_QVA)
                    191: // Used for ISA and PCI bus I/O accesses in sparse space.
                    192: 
                    193: #define OTHER_QVA        0xa0000000          // (QVA_ENABLE | 0x00000000)
                    194: 
                    195: #define IO_BIT_SHIFT     0x05               // Bits to shift address
                    196: 
                    197: #define        IO_BYTE_LEN      0x00                // Byte length
                    198: #define        IO_WORD_LEN      0x08                // Word length
                    199: #define IO_LONG_LEN     0x18                // LONGWORD length
                    200: 
                    201: 
                    202: /*++
                    203: 
                    204: UCHAR
                    205: READ_PORT_Usize(
                    206:     volatile PUsize Port
                    207:     )
                    208: 
                    209: Routine Description:
                    210: 
                    211:     Read from the specified I/O port (CSR) address.
                    212: 
                    213:     Note these macros do *not* perform a memory barrier. The
                    214:     rationale for this is that reading from a CSR is informative,
                    215:     rather than active. This is a weak rationale, but fits in OK
                    216:     with the VGA driver. Trying to use this module for other
                    217:     purposes may require the use of memory barriers.
                    218: 
                    219: Arguments:
                    220: 
                    221:     Port - Supplies a pointer to the port in I/O space.
                    222: 
                    223: Return Value:
                    224: 
                    225:     Returns the value read from the specified port address.
                    226: 
                    227: --*/
                    228: 
                    229: #define READ_PORT_UCHAR READ_REGISTER_UCHAR
                    230: 
                    231: #define READ_PORT_USHORT READ_REGISTER_USHORT
                    232: 
                    233: #define READ_PORT_ULONG READ_REGISTER_ULONG
                    234: 
                    235: /*++
                    236: 
                    237: VOID
                    238: WRITE_PORT_Usize(
                    239:     volatile PUsize Port,
                    240:     Usize Value
                    241:     )
                    242: 
                    243: Routine Description:
                    244: 
                    245:     Write to the specified port (CSR) address.
                    246: 
                    247:     Note we perform a memory barrier before we modify the CSR. The
                    248:     rationale for this is that writing to a CSR clearly has active
                    249:     effects, and thus all writes that take place before the CSR is
                    250:     changed must be completed before the CSR change takes effect.
                    251: 
                    252:     We also perform a memory barrier after we modify the CSR. The
                    253:     rationale for this is that any writes which follow the CSR
                    254:     modification may be affected by the change in state, and thus
                    255:     must be ordered with respect to the CSR modification.
                    256: 
                    257:     Note that if you're updating multiple CSRs in a row, there will
                    258:     be more memory barriers than needed. Do we want another set of
                    259:     macros to get around this?
                    260: 
                    261:     The QUICK_WRITE_PORT_Usize functions perform the same functions
                    262:     as their WRITE_PORT_Usize variants, except they do *not* execute
                    263:     memory barriers. The invoker is responsible for using the
                    264:     MEMORY_BARRIER function to synchronize with the write buffers and 
                    265:     cache.
                    266: 
                    267: Arguments:
                    268: 
                    269:     Port - Supplies a pointer to the port in I/O space.
                    270:     Value  - The value to be written to the port.
                    271: 
                    272: Return Value:
                    273: 
                    274:     None
                    275: 
                    276: --*/
                    277: 
                    278: #define WRITE_PORT_UCHAR(Port,Value)                \
                    279:                                                \
                    280:     MEMORY_BARRIER();                           \
                    281:     WRITE_REGISTER_UCHAR ((Port), (Value));     \
                    282:     MEMORY_BARRIER();                            \
                    283:      
                    284: 
                    285: #define QUICK_WRITE_PORT_UCHAR(Port,Value)        \
                    286:     WRITE_REGISTER_UCHAR ((Port), (Value))
                    287: 
                    288: #define WRITE_PORT_USHORT(Port,Value)                \
                    289:                                                \
                    290:     MEMORY_BARRIER();                           \
                    291:     WRITE_REGISTER_USHORT ((Port), (Value));    \
                    292:     MEMORY_BARRIER();                            \
                    293:     
                    294: 
                    295: #define QUICK_WRITE_PORT_USHORT(Port,Value)        \
                    296:     WRITE_REGISTER_USHORT ((Port), (Value))
                    297: 
                    298: #define WRITE_PORT_ULONG(Port,Value)                \
                    299:                                                \
                    300:     MEMORY_BARRIER();                           \
                    301:     WRITE_REGISTER_ULONG ((Port), (Value));     \
                    302:     MEMORY_BARRIER();                            \
                    303:     
                    304: 
                    305: #define QUICK_WRITE_PORT_ULONG(Port,Value)        \
                    306:     WRITE_REGISTER_ULONG ((Port), (Value))
                    307: 
                    308: /*++
                    309: 
                    310: UCHAR
                    311: READ_REGISTER_Usize(
                    312:     volatile PUsize Register
                    313:     )
                    314: 
                    315: Routine Description:
                    316: 
                    317:     Read from the specified register address.
                    318: 
                    319: Arguments:
                    320: 
                    321:     Register - Supplies a pointer to the register in I/O space.
                    322: 
                    323: Return Value:
                    324: 
                    325:     Returns the value read from the specified register address.
                    326: 
                    327: --*/
                    328: 
                    329: #define READ_REGISTER_UCHAR(Register)                                               \
                    330:    ( \
                    331:     ( ((ULONG) (Register) & QVA_SELECTORS) == OTHER_QVA )  ?                        \
                    332:     ((UCHAR)((*(volatile ULONG *)((((ULONG)(Register)             \
                    333:          ) << IO_BIT_SHIFT)   | IO_BYTE_LEN  )) >> (((ULONG)(Register) & 3) * 8)))  \
                    334:    : \
                    335:     ((UCHAR)((*(volatile ULONG *)((((ULONG)(Register)             \
                    336:          ) << EISA_BIT_SHIFT) | EISA_BYTE_LEN)) >> (((ULONG)(Register) & 3) * 8)))  \
                    337:    )
                    338: 
                    339: #define READ_REGISTER_USHORT(Register)                                              \
                    340:    ( \
                    341:     ( ((ULONG) (Register) & QVA_SELECTORS) == OTHER_QVA )  ?                        \
                    342:     ((USHORT)((*(volatile ULONG *)((((ULONG)(Register)            \
                    343:          ) << IO_BIT_SHIFT)   | IO_WORD_LEN  )) >> (((ULONG)(Register) & 3) * 8)))  \
                    344:    : \
                    345:     ((USHORT)((*(volatile ULONG *)((((ULONG)(Register)            \
                    346:          ) << EISA_BIT_SHIFT) | EISA_WORD_LEN)) >> (((ULONG)(Register) & 3) * 8)))  \
                    347:    )
                    348: 
                    349: #define READ_REGISTER_ULONG(Register)                                                \
                    350:     ( \
                    351:      ( ((ULONG) (Register) & QVA_SELECTORS) == OTHER_QVA )  ?                        \
                    352:      (*(volatile ULONG *)((((ULONG)(Register) ) << IO_BIT_SHIFT) | IO_LONG_LEN))     \
                    353:     : \
                    354:      (*(volatile ULONG *)((((ULONG)(Register) ) << EISA_BIT_SHIFT) | EISA_LONG_LEN)) \
                    355:     )
                    356: 
                    357: 
                    358: /*++
                    359: 
                    360: VOID
                    361: WRITE_REGISTER_Usize(
                    362:     volatile PUsize Register,
                    363:     Usize Value
                    364:     )
                    365: 
                    366: Routine Description:
                    367: 
                    368:     Write to the specified register address.
                    369: 
                    370: Arguments:
                    371: 
                    372:     Register - Supplies a pointer to the register in I/O space.
                    373:     Value  - The value to be written to the register.
                    374: 
                    375: Return Value:
                    376: 
                    377:     None
                    378: 
                    379: --*/
                    380: 
                    381: #define WRITE_REGISTER_UCHAR(Register,Value)                \
                    382:   if ( (((ULONG) (Register)) & QVA_SELECTORS) == OTHER_QVA)  \
                    383:     (*(volatile ULONG *)((((ULONG)(Register) ) << IO_BIT_SHIFT) | IO_BYTE_LEN) =    \
                    384:         (ULONG)((ULONG)(Value) << (((ULONG)(Register) & 3) * 8)));  \
                    385:   else \
                    386:     (*(volatile ULONG *)((((ULONG)(Register) ) << EISA_BIT_SHIFT) | EISA_BYTE_LEN) = \
                    387:         (ULONG)((ULONG)(Value) << (((ULONG)(Register) & 3) * 8)));
                    388: 
                    389: 
                    390: #define WRITE_REGISTER_USHORT(Register,Value)                \
                    391:  if ( (((ULONG) (Register)) & QVA_SELECTORS) == OTHER_QVA) \
                    392:     (*(volatile ULONG *)((((ULONG)(Register) ) << IO_BIT_SHIFT) | IO_WORD_LEN) =        \
                    393:         (ULONG)((ULONG)(Value) << (((ULONG)(Register) & 3) * 8)));  \
                    394:  else \
                    395:     (*(volatile ULONG *)((((ULONG)(Register) ) << EISA_BIT_SHIFT) | EISA_WORD_LEN) =        \
                    396:         (ULONG)((ULONG)(Value) << (((ULONG)(Register) & 3) * 8))) ; 
                    397: 
                    398: 
                    399: #define WRITE_REGISTER_ULONG(Register,Value)                \
                    400:  if ( (((ULONG) (Register)) & QVA_SELECTORS) == OTHER_QVA)  \
                    401:     (*(volatile ULONG *)((((ULONG)(Register) ) << IO_BIT_SHIFT) | IO_LONG_LEN) =        \
                    402:         (ULONG)(Value)) ; \
                    403:  else \
                    404:     (*(volatile ULONG *)((((ULONG)(Register) ) << EISA_BIT_SHIFT) | EISA_LONG_LEN) =        \
                    405:         (ULONG)(Value)); 
                    406: 
                    407: 
                    408: 
                    409: #endif // defined(ALPHA)
                    410: 
                    411: 
                    412: #if defined(MIPS)
                    413: 
                    414: //
                    415: // There is no such thing as a memory barrier on MIPS ...
                    416: //
                    417: 
                    418: #define MEMORY_BARRIER()
                    419: 
                    420: 
                    421: /*++
                    422: 
                    423: UCHAR
                    424: READ_WRITE_PORT_Usize(
                    425:     volatile PUsize Port
                    426:     )
                    427: 
                    428: Routine Description:
                    429: 
                    430:     Read from the specified I/O port (CSR) address.
                    431: 
                    432:     Note these macros do *not* perform a memory barrier. The
                    433:     rationale for this is that reading from a CSR is informative,
                    434:     rather than active. This is a weak rationale, but fits in OK
                    435:     with the VGA driver. Trying to use this module for other
                    436:     purposes may require the use of memory barriers.
                    437: 
                    438: Arguments:
                    439: 
                    440:     Port - Supplies a pointer to the port in I/O space.
                    441: 
                    442: Return Value:
                    443: 
                    444:     Returns the value read from the specified port address.
                    445: 
                    446: --*/
                    447: 
                    448: #define READ_PORT_UCHAR(A) READ_REGISTER_UCHAR((PUCHAR)(A))
                    449: 
                    450: #define READ_PORT_USHORT(A) READ_REGISTER_USHORT((PUSHORT)(A))
                    451: 
                    452: #define READ_PORT_ULONG(A) READ_REGISTER_ULONG((PULONG)(A))
                    453: 
                    454: #define WRITE_PORT_UCHAR(A,V) WRITE_REGISTER_UCHAR((PUCHAR)(A),(UCHAR)(V))
                    455: 
                    456: #define WRITE_PORT_USHORT(A,V) WRITE_REGISTER_USHORT((PUSHORT)(A),(USHORT)(V))
                    457: 
                    458: #define WRITE_PORT_ULONG(A,V) WRITE_REGISTER_ULONG((PULONG)(A),(ULONG)(V))
                    459: 
                    460: 
                    461: /*++
                    462: 
                    463: UCHAR
                    464: READ_REGISTER_Usize(
                    465:     volatile PUsize Register
                    466:     )
                    467: 
                    468: Routine Description:
                    469: 
                    470:     Read from the specified register address.
                    471: 
                    472: Arguments:
                    473: 
                    474:     Register - Supplies a pointer to the register in I/O space.
                    475: 
                    476: Return Value:
                    477: 
                    478:     Returns the value read from the specified register address.
                    479: 
                    480: --*/
                    481: 
                    482: #define READ_REGISTER_UCHAR(x) \
                    483:     (*(volatile UCHAR * const)(x))
                    484: 
                    485: #define READ_REGISTER_USHORT(x) \
                    486:     (*(volatile USHORT * const)(x))
                    487: 
                    488: #define READ_REGISTER_ULONG(x) \
                    489:     (*(volatile ULONG * const)(x))
                    490: 
                    491: 
                    492: /*++
                    493: 
                    494: VOID
                    495: WRITE_REGISTER_Usize(
                    496:     volatile PUsize Register,
                    497:     Usize Value
                    498:     )
                    499: 
                    500: Routine Description:
                    501: 
                    502:     Write to the specified register address.
                    503: 
                    504: Arguments:
                    505: 
                    506:     Register - Supplies a pointer to the register in I/O space.
                    507:     Value  - The value to be written to the register.
                    508: 
                    509: Return Value:
                    510: 
                    511:     None
                    512: 
                    513: --*/
                    514: 
                    515: #define WRITE_REGISTER_UCHAR(x, y) \
                    516:     (*(volatile UCHAR * const)(x) = (y))
                    517: 
                    518: #define WRITE_REGISTER_USHORT(x, y) \
                    519:     (*(volatile USHORT * const)(x) = (y))
                    520: 
                    521: #define WRITE_REGISTER_ULONG(x, y) \
                    522:     (*(volatile ULONG * const)(x) = (y))
                    523: 
                    524: #endif // defined(MIPS)
                    525: 
                    526: #endif // _IOACCESS_

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.