Home | History | Annotate | Download | only in DxeIoLibCpuIo
      1 /** @file
      2   I/O Library.
      3   The implementation of I/O operation for this library instance
      4   are based on EFI_CPU_IO_PROTOCOL.
      5 
      6   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
      7   This program and the accompanying materials
      8   are licensed and made available under the terms and conditions of the BSD License
      9   which accompanies this distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15   Module Name:  IoLib.c
     16 
     17 **/
     18 
     19 
     20 #include "DxeCpuIoLibInternal.h"
     21 
     22 //
     23 // Globle varible to cache pointer to CpuIo protocol.
     24 //
     25 EFI_CPU_IO_PROTOCOL  *mCpuIo = NULL;
     26 
     27 /**
     28   The constructor function caches the pointer to CpuIo protocol.
     29 
     30   The constructor function locates CpuIo protocol from protocol database.
     31   It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
     32 
     33   @param  ImageHandle   The firmware allocated handle for the EFI image.
     34   @param  SystemTable   A pointer to the EFI System Table.
     35 
     36   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
     37 
     38 **/
     39 EFI_STATUS
     40 EFIAPI
     41 IoLibConstructor (
     42   IN      EFI_HANDLE                ImageHandle,
     43   IN      EFI_SYSTEM_TABLE          *SystemTable
     44   )
     45 {
     46   EFI_STATUS  Status;
     47 
     48   Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo);
     49   ASSERT_EFI_ERROR (Status);
     50 
     51   return Status;
     52 }
     53 
     54 /**
     55   Reads registers in the EFI CPU I/O space.
     56 
     57   Reads the I/O port specified by Port with registers width specified by Width.
     58   The read value is returned. If such operations are not supported, then ASSERT().
     59   This function must guarantee that all I/O read and write operations are serialized.
     60 
     61   @param  Port          The base address of the I/O operation.
     62                         The caller is responsible for aligning the Address if required.
     63   @param  Width         The width of the I/O operation.
     64 
     65   @return Data read from registers in the EFI CPU I/O space.
     66 
     67 **/
     68 UINT64
     69 EFIAPI
     70 IoReadWorker (
     71   IN      UINTN                      Port,
     72   IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width
     73   )
     74 {
     75   EFI_STATUS                        Status;
     76   UINT64                            Data;
     77 
     78   Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);
     79   ASSERT_EFI_ERROR (Status);
     80 
     81   return Data;
     82 }
     83 
     84 /**
     85   Writes registers in the EFI CPU I/O space.
     86 
     87   Writes the I/O port specified by Port with registers width and value specified by Width
     88   and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().
     89   This function must guarantee that all I/O read and write operations are serialized.
     90 
     91   @param  Port          The base address of the I/O operation.
     92                         The caller is responsible for aligning the Address if required.
     93   @param  Width         The width of the I/O operation.
     94   @param  Data          The value to write to the I/O port.
     95 
     96   @return The paramter of Data.
     97 
     98 **/
     99 UINT64
    100 EFIAPI
    101 IoWriteWorker (
    102   IN      UINTN                      Port,
    103   IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width,
    104   IN      UINT64                     Data
    105   )
    106 {
    107   EFI_STATUS  Status;
    108 
    109   Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);
    110   ASSERT_EFI_ERROR (Status);
    111 
    112   return Data;
    113 }
    114 
    115 /**
    116   Reads memory-mapped registers in the EFI system memory space.
    117 
    118   Reads the MMIO registers specified by Address with registers width specified by Width.
    119   The read value is returned. If such operations are not supported, then ASSERT().
    120   This function must guarantee that all MMIO read and write operations are serialized.
    121 
    122   @param  Address       The MMIO register to read.
    123                         The caller is responsible for aligning the Address if required.
    124   @param  Width         The width of the I/O operation.
    125 
    126   @return Data read from registers in the EFI system memory space.
    127 
    128 **/
    129 UINT64
    130 EFIAPI
    131 MmioReadWorker (
    132   IN      UINTN                      Address,
    133   IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width
    134   )
    135 {
    136   EFI_STATUS  Status;
    137   UINT64      Data;
    138 
    139   Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);
    140   ASSERT_EFI_ERROR (Status);
    141 
    142   return Data;
    143 }
    144 
    145 /**
    146   Writes memory-mapped registers in the EFI system memory space.
    147 
    148   Writes the MMIO registers specified by Address with registers width and value specified by Width
    149   and Data respectively. Data is returned. If such operations are not supported, then ASSERT().
    150   This function must guarantee that all MMIO read and write operations are serialized.
    151 
    152   @param  Address       The MMIO register to read.
    153                         The caller is responsible for aligning the Address if required.
    154   @param  Width         The width of the I/O operation.
    155   @param  Data          The value to write to the I/O port.
    156 
    157   @return Data read from registers in the EFI system memory space.
    158 
    159 **/
    160 UINT64
    161 EFIAPI
    162 MmioWriteWorker (
    163   IN      UINTN                      Address,
    164   IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width,
    165   IN      UINT64                     Data
    166   )
    167 {
    168   EFI_STATUS  Status;
    169 
    170   Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);
    171   ASSERT_EFI_ERROR (Status);
    172 
    173   return Data;
    174 }
    175 
    176 /**
    177   Reads an 8-bit I/O port.
    178 
    179   Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
    180   This function must guarantee that all I/O read and write operations are
    181   serialized.
    182 
    183   If 8-bit I/O port operations are not supported, then ASSERT().
    184 
    185   @param  Port  The I/O port to read.
    186 
    187   @return The value read.
    188 
    189 **/
    190 UINT8
    191 EFIAPI
    192 IoRead8 (
    193   IN      UINTN                     Port
    194   )
    195 {
    196   return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);
    197 }
    198 
    199 /**
    200   Writes an 8-bit I/O port.
    201 
    202   Writes the 8-bit I/O port specified by Port with the value specified by Value
    203   and returns Value. This function must guarantee that all I/O read and write
    204   operations are serialized.
    205 
    206   If 8-bit I/O port operations are not supported, then ASSERT().
    207 
    208   @param  Port  The I/O port to write.
    209   @param  Value The value to write to the I/O port.
    210 
    211   @return The value written the I/O port.
    212 
    213 **/
    214 UINT8
    215 EFIAPI
    216 IoWrite8 (
    217   IN      UINTN                     Port,
    218   IN      UINT8                     Value
    219   )
    220 {
    221   return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);
    222 }
    223 
    224 /**
    225   Reads a 16-bit I/O port.
    226 
    227   Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
    228   This function must guarantee that all I/O read and write operations are
    229   serialized.
    230 
    231   If Port is not aligned on a 16-bit boundary, then ASSERT().
    232 
    233   If 16-bit I/O port operations are not supported, then ASSERT().
    234 
    235   @param  Port  The I/O port to read.
    236 
    237   @return The value read.
    238 
    239 **/
    240 UINT16
    241 EFIAPI
    242 IoRead16 (
    243   IN      UINTN                     Port
    244   )
    245 {
    246   //
    247   // Make sure Port is aligned on a 16-bit boundary.
    248   //
    249   ASSERT ((Port & 1) == 0);
    250   return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);
    251 }
    252 
    253 /**
    254   Writes a 16-bit I/O port.
    255 
    256   Writes the 16-bit I/O port specified by Port with the value specified by Value
    257   and returns Value. This function must guarantee that all I/O read and write
    258   operations are serialized.
    259 
    260   If Port is not aligned on a 16-bit boundary, then ASSERT().
    261 
    262   If 16-bit I/O port operations are not supported, then ASSERT().
    263 
    264   @param  Port  The I/O port to write.
    265   @param  Value The value to write to the I/O port.
    266 
    267   @return The value written the I/O port.
    268 
    269 **/
    270 UINT16
    271 EFIAPI
    272 IoWrite16 (
    273   IN      UINTN                     Port,
    274   IN      UINT16                    Value
    275   )
    276 {
    277   //
    278   // Make sure Port is aligned on a 16-bit boundary.
    279   //
    280   ASSERT ((Port & 1) == 0);
    281   return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);
    282 }
    283 
    284 /**
    285   Reads a 32-bit I/O port.
    286 
    287   Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
    288   This function must guarantee that all I/O read and write operations are
    289   serialized.
    290 
    291   If Port is not aligned on a 32-bit boundary, then ASSERT().
    292 
    293   If 32-bit I/O port operations are not supported, then ASSERT().
    294 
    295   @param  Port  The I/O port to read.
    296 
    297   @return The value read.
    298 
    299 **/
    300 UINT32
    301 EFIAPI
    302 IoRead32 (
    303   IN      UINTN                     Port
    304   )
    305 {
    306   //
    307   // Make sure Port is aligned on a 32-bit boundary.
    308   //
    309   ASSERT ((Port & 3) == 0);
    310   return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);
    311 }
    312 
    313 /**
    314   Writes a 32-bit I/O port.
    315 
    316   Writes the 32-bit I/O port specified by Port with the value specified by Value
    317   and returns Value. This function must guarantee that all I/O read and write
    318   operations are serialized.
    319 
    320   If Port is not aligned on a 32-bit boundary, then ASSERT().
    321 
    322   If 32-bit I/O port operations are not supported, then ASSERT().
    323 
    324   @param  Port  The I/O port to write.
    325   @param  Value The value to write to the I/O port.
    326 
    327   @return The value written the I/O port.
    328 
    329 **/
    330 UINT32
    331 EFIAPI
    332 IoWrite32 (
    333   IN      UINTN                     Port,
    334   IN      UINT32                    Value
    335   )
    336 {
    337   //
    338   // Make sure Port is aligned on a 32-bit boundary.
    339   //
    340   ASSERT ((Port & 3) == 0);
    341   return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);
    342 }
    343 
    344 /**
    345   Reads a 64-bit I/O port.
    346 
    347   Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
    348   This function must guarantee that all I/O read and write operations are
    349   serialized.
    350 
    351   If Port is not aligned on a 64-bit boundary, then ASSERT().
    352 
    353   If 64-bit I/O port operations are not supported, then ASSERT().
    354 
    355   @param  Port  The I/O port to read.
    356 
    357   @return The value read.
    358 
    359 **/
    360 UINT64
    361 EFIAPI
    362 IoRead64 (
    363   IN      UINTN                     Port
    364   )
    365 {
    366   //
    367   // Make sure Port is aligned on a 64-bit boundary.
    368   //
    369   ASSERT ((Port & 7) == 0);
    370   return IoReadWorker (Port, EfiCpuIoWidthUint64);
    371 }
    372 
    373 /**
    374   Writes a 64-bit I/O port.
    375 
    376   Writes the 64-bit I/O port specified by Port with the value specified by Value
    377   and returns Value. This function must guarantee that all I/O read and write
    378   operations are serialized.
    379 
    380   If Port is not aligned on a 64-bit boundary, then ASSERT().
    381 
    382   If 64-bit I/O port operations are not supported, then ASSERT().
    383 
    384   @param  Port  The I/O port to write.
    385   @param  Value The value to write to the I/O port.
    386 
    387   @return The value written the I/O port.
    388 
    389 **/
    390 UINT64
    391 EFIAPI
    392 IoWrite64 (
    393   IN      UINTN                     Port,
    394   IN      UINT64                    Value
    395   )
    396 {
    397   //
    398   // Make sure Port is aligned on a 64-bit boundary.
    399   //
    400   ASSERT ((Port & 7) == 0);
    401   return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);
    402 }
    403 
    404 /**
    405   Reads an 8-bit MMIO register.
    406 
    407   Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
    408   returned. This function must guarantee that all MMIO read and write
    409   operations are serialized.
    410 
    411   If 8-bit MMIO register operations are not supported, then ASSERT().
    412 
    413   @param  Address The MMIO register to read.
    414 
    415   @return The value read.
    416 
    417 **/
    418 UINT8
    419 EFIAPI
    420 MmioRead8 (
    421   IN      UINTN                     Address
    422   )
    423 {
    424   return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);
    425 }
    426 
    427 /**
    428   Writes an 8-bit MMIO register.
    429 
    430   Writes the 8-bit MMIO register specified by Address with the value specified
    431   by Value and returns Value. This function must guarantee that all MMIO read
    432   and write operations are serialized.
    433 
    434   If 8-bit MMIO register operations are not supported, then ASSERT().
    435 
    436   @param  Address The MMIO register to write.
    437   @param  Value   The value to write to the MMIO register.
    438 
    439 **/
    440 UINT8
    441 EFIAPI
    442 MmioWrite8 (
    443   IN      UINTN                     Address,
    444   IN      UINT8                     Value
    445   )
    446 {
    447   return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);
    448 }
    449 
    450 /**
    451   Reads a 16-bit MMIO register.
    452 
    453   Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
    454   returned. This function must guarantee that all MMIO read and write
    455   operations are serialized.
    456 
    457   If Address is not aligned on a 16-bit boundary, then ASSERT().
    458 
    459   If 16-bit MMIO register operations are not supported, then ASSERT().
    460 
    461   @param  Address The MMIO register to read.
    462 
    463   @return The value read.
    464 
    465 **/
    466 UINT16
    467 EFIAPI
    468 MmioRead16 (
    469   IN      UINTN                     Address
    470   )
    471 {
    472   //
    473   // Make sure Address is aligned on a 16-bit boundary.
    474   //
    475   ASSERT ((Address & 1) == 0);
    476   return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);
    477 }
    478 
    479 /**
    480   Writes a 16-bit MMIO register.
    481 
    482   Writes the 16-bit MMIO register specified by Address with the value specified
    483   by Value and returns Value. This function must guarantee that all MMIO read
    484   and write operations are serialized.
    485 
    486   If Address is not aligned on a 16-bit boundary, then ASSERT().
    487 
    488   If 16-bit MMIO register operations are not supported, then ASSERT().
    489 
    490   @param  Address The MMIO register to write.
    491   @param  Value   The value to write to the MMIO register.
    492 
    493 **/
    494 UINT16
    495 EFIAPI
    496 MmioWrite16 (
    497   IN      UINTN                     Address,
    498   IN      UINT16                    Value
    499   )
    500 {
    501   //
    502   // Make sure Address is aligned on a 16-bit boundary.
    503   //
    504   ASSERT ((Address & 1) == 0);
    505   return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);
    506 }
    507 
    508 /**
    509   Reads a 32-bit MMIO register.
    510 
    511   Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
    512   returned. This function must guarantee that all MMIO read and write
    513   operations are serialized.
    514 
    515   If Address is not aligned on a 32-bit boundary, then ASSERT().
    516 
    517   If 32-bit MMIO register operations are not supported, then ASSERT().
    518 
    519   @param  Address The MMIO register to read.
    520 
    521   @return The value read.
    522 
    523 **/
    524 UINT32
    525 EFIAPI
    526 MmioRead32 (
    527   IN      UINTN                     Address
    528   )
    529 {
    530   //
    531   // Make sure Address is aligned on a 32-bit boundary.
    532   //
    533   ASSERT ((Address & 3) == 0);
    534   return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);
    535 }
    536 
    537 /**
    538   Writes a 32-bit MMIO register.
    539 
    540   Writes the 32-bit MMIO register specified by Address with the value specified
    541   by Value and returns Value. This function must guarantee that all MMIO read
    542   and write operations are serialized.
    543 
    544   If Address is not aligned on a 32-bit boundary, then ASSERT().
    545 
    546   If 32-bit MMIO register operations are not supported, then ASSERT().
    547 
    548   @param  Address The MMIO register to write.
    549   @param  Value   The value to write to the MMIO register.
    550 
    551 **/
    552 UINT32
    553 EFIAPI
    554 MmioWrite32 (
    555   IN      UINTN                     Address,
    556   IN      UINT32                    Value
    557   )
    558 {
    559   //
    560   // Make sure Address is aligned on a 32-bit boundary.
    561   //
    562   ASSERT ((Address & 3) == 0);
    563   return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);
    564 }
    565 
    566 /**
    567   Reads a 64-bit MMIO register.
    568 
    569   Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
    570   returned. This function must guarantee that all MMIO read and write
    571   operations are serialized.
    572 
    573   If Address is not aligned on a 64-bit boundary, then ASSERT().
    574 
    575   If 64-bit MMIO register operations are not supported, then ASSERT().
    576 
    577   @param  Address The MMIO register to read.
    578 
    579   @return The value read.
    580 
    581 **/
    582 UINT64
    583 EFIAPI
    584 MmioRead64 (
    585   IN      UINTN                     Address
    586   )
    587 {
    588   //
    589   // Make sure Address is aligned on a 64-bit boundary.
    590   //
    591   ASSERT ((Address & 7) == 0);
    592   return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);
    593 }
    594 
    595 /**
    596   Writes a 64-bit MMIO register.
    597 
    598   Writes the 64-bit MMIO register specified by Address with the value specified
    599   by Value and returns Value. This function must guarantee that all MMIO read
    600   and write operations are serialized.
    601 
    602   If Address is not aligned on a 64-bit boundary, then ASSERT().
    603 
    604   If 64-bit MMIO register operations are not supported, then ASSERT().
    605 
    606   @param  Address The MMIO register to write.
    607   @param  Value   The value to write to the MMIO register.
    608 
    609 **/
    610 UINT64
    611 EFIAPI
    612 MmioWrite64 (
    613   IN      UINTN                     Address,
    614   IN      UINT64                    Value
    615   )
    616 {
    617   //
    618   // Make sure Address is aligned on a 64-bit boundary.
    619   //
    620   ASSERT ((Address & 7) == 0);
    621   return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);
    622 }
    623