Home | History | Annotate | Download | only in BaseIoLibIntrinsic
      1 /** @file
      2   I/O Library. This file has compiler specifics for GCC as there is no
      3   ANSI C standard for doing IO.
      4 
      5   GCC - uses EFIAPI assembler. __asm__ calls GAS. __volatile__ makes sure the
      6   compiler puts the assembler in this exact location. The complex GNUC
      7   operations are not optimzed. It would be possible to also write these
      8   with EFIAPI assembler.
      9 
     10   We don't advocate putting compiler specifics in libraries or drivers but there
     11   is no other way to make this work.
     12 
     13   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
     14   This program and the accompanying materials
     15   are licensed and made available under the terms and conditions of the BSD License
     16   which accompanies this distribution.  The full text of the license may be found at
     17   http://opensource.org/licenses/bsd-license.php.
     18 
     19   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     20   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     21 
     22 **/
     23 
     24 
     25 #include "BaseIoLibIntrinsicInternal.h"
     26 
     27 /**
     28   Reads an 8-bit I/O port.
     29 
     30   Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
     31   This function must guarantee that all I/O read and write operations are
     32   serialized.
     33 
     34   If 8-bit I/O port operations are not supported, then ASSERT().
     35 
     36   @param  Port  The I/O port to read.
     37 
     38   @return The value read.
     39 
     40 **/
     41 __inline__
     42 UINT8
     43 EFIAPI
     44 IoRead8 (
     45   IN      UINTN                     Port
     46   )
     47 {
     48   UINT8   Data;
     49 
     50   __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
     51   return Data;
     52 }
     53 
     54 /**
     55   Writes an 8-bit I/O port.
     56 
     57   Writes the 8-bit I/O port specified by Port with the value specified by Value
     58   and returns Value. This function must guarantee that all I/O read and write
     59   operations are serialized.
     60 
     61   If 8-bit I/O port operations are not supported, then ASSERT().
     62 
     63   @param  Port  The I/O port to write.
     64   @param  Value The value to write to the I/O port.
     65 
     66   @return The value written the I/O port.
     67 
     68 **/
     69 __inline__
     70 UINT8
     71 EFIAPI
     72 IoWrite8 (
     73   IN      UINTN                     Port,
     74   IN      UINT8                     Value
     75   )
     76 {
     77   __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
     78   return Value;;
     79 }
     80 
     81 /**
     82   Reads a 16-bit I/O port.
     83 
     84   Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
     85   This function must guarantee that all I/O read and write operations are
     86   serialized.
     87 
     88   If 16-bit I/O port operations are not supported, then ASSERT().
     89   If Port is not aligned on a 16-bit boundary, then ASSERT().
     90 
     91   @param  Port  The I/O port to read.
     92 
     93   @return The value read.
     94 
     95 **/
     96 __inline__
     97 UINT16
     98 EFIAPI
     99 IoRead16 (
    100   IN      UINTN                     Port
    101   )
    102 {
    103   UINT16   Data;
    104 
    105   ASSERT ((Port & 1) == 0);
    106   __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
    107   return Data;
    108 }
    109 
    110 /**
    111   Writes a 16-bit I/O port.
    112 
    113   Writes the 16-bit I/O port specified by Port with the value specified by Value
    114   and returns Value. This function must guarantee that all I/O read and write
    115   operations are serialized.
    116 
    117   If 16-bit I/O port operations are not supported, then ASSERT().
    118   If Port is not aligned on a 16-bit boundary, then ASSERT().
    119 
    120   @param  Port  The I/O port to write.
    121   @param  Value The value to write to the I/O port.
    122 
    123   @return The value written the I/O port.
    124 
    125 **/
    126 __inline__
    127 UINT16
    128 EFIAPI
    129 IoWrite16 (
    130   IN      UINTN                     Port,
    131   IN      UINT16                    Value
    132   )
    133 {
    134   ASSERT ((Port & 1) == 0);
    135   __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
    136   return Value;;
    137 }
    138 
    139 /**
    140   Reads a 32-bit I/O port.
    141 
    142   Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
    143   This function must guarantee that all I/O read and write operations are
    144   serialized.
    145 
    146   If 32-bit I/O port operations are not supported, then ASSERT().
    147   If Port is not aligned on a 32-bit boundary, then ASSERT().
    148 
    149   @param  Port  The I/O port to read.
    150 
    151   @return The value read.
    152 
    153 **/
    154 __inline__
    155 UINT32
    156 EFIAPI
    157 IoRead32 (
    158   IN      UINTN                     Port
    159   )
    160 {
    161   UINT32   Data;
    162 
    163   ASSERT ((Port & 3) == 0);
    164   __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
    165   return Data;
    166 }
    167 
    168 /**
    169   Writes a 32-bit I/O port.
    170 
    171   Writes the 32-bit I/O port specified by Port with the value specified by Value
    172   and returns Value. This function must guarantee that all I/O read and write
    173   operations are serialized.
    174 
    175   If 32-bit I/O port operations are not supported, then ASSERT().
    176   If Port is not aligned on a 32-bit boundary, then ASSERT().
    177 
    178   @param  Port  The I/O port to write.
    179   @param  Value The value to write to the I/O port.
    180 
    181   @return The value written the I/O port.
    182 
    183 **/
    184 __inline__
    185 UINT32
    186 EFIAPI
    187 IoWrite32 (
    188   IN      UINTN                     Port,
    189   IN      UINT32                    Value
    190   )
    191 {
    192   ASSERT ((Port & 3) == 0);
    193   __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
    194   return Value;
    195 }
    196 
    197