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
IoRead8(IN UINTN Port)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
IoWrite8(IN UINTN Port,IN UINT8 Value)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
IoRead16(IN UINTN Port)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
IoWrite16(IN UINTN Port,IN UINT16 Value)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
IoRead32(IN UINTN Port)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
IoWrite32(IN UINTN Port,IN UINT32 Value)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