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