]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
05a739085967c1390ea5ebb5f42ba5cac31acd06
[mirror_edk2.git] / MdePkg / Library / BaseIoLibIntrinsic / IoLibGcc.c
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 - 2021, Intel Corporation. All rights reserved.<BR>
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15
16 **/
17
18 #include "BaseIoLibIntrinsicInternal.h"
19 #include "IoLibTdx.h"
20
21 /**
22 Reads an 8-bit I/O port.
23
24 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
25 This function must guarantee that all I/O read and write operations are
26 serialized.
27
28 If 8-bit I/O port operations are not supported, then ASSERT()
29
30 For Td guest TDVMCALL_IO is invoked to read I/O port.
31
32 @param Port The I/O port to read.
33
34 @return The value read.
35
36 **/
37 UINT8
38 EFIAPI
39 IoRead8 (
40 IN UINTN Port
41 )
42 {
43 UINT8 Data;
44 BOOLEAN Flag;
45
46 Flag = FilterBeforeIoRead (FilterWidth8, Port, &Data);
47 if (Flag) {
48 if (IsTdxGuest ()) {
49 Data = TdIoRead8 (Port);
50 } else {
51 __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
52 }
53 }
54
55 FilterAfterIoRead (FilterWidth8, Port, &Data);
56
57 return Data;
58 }
59
60 /**
61 Writes an 8-bit I/O port.
62
63 Writes the 8-bit I/O port specified by Port with the value specified by Value
64 and returns Value. This function must guarantee that all I/O read and write
65 operations are serialized.
66
67 If 8-bit I/O port operations are not supported, then ASSERT().
68
69 For Td guest TDVMCALL_IO is invoked to write I/O port.
70
71 @param Port The I/O port to write.
72 @param Value The value to write to the I/O port.
73
74 @return The value written the I/O port.
75
76 **/
77 UINT8
78 EFIAPI
79 IoWrite8 (
80 IN UINTN Port,
81 IN UINT8 Value
82 )
83 {
84 BOOLEAN Flag;
85
86 Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value);
87 if (Flag) {
88 if (IsTdxGuest ()) {
89 TdIoWrite8 (Port, Value);
90 } else {
91 __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
92 }
93 }
94
95 FilterAfterIoWrite (FilterWidth8, Port, &Value);
96
97 return Value;
98 }
99
100 /**
101 Reads a 16-bit I/O port.
102
103 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
104 This function must guarantee that all I/O read and write operations are
105 serialized.
106
107 If 16-bit I/O port operations are not supported, then ASSERT().
108 If Port is not aligned on a 16-bit boundary, then ASSERT().
109
110 For Td guest TDVMCALL_IO is invoked to read I/O port.
111
112 @param Port The I/O port to read.
113
114 @return The value read.
115
116 **/
117 UINT16
118 EFIAPI
119 IoRead16 (
120 IN UINTN Port
121 )
122 {
123 UINT16 Data;
124 BOOLEAN Flag;
125
126 ASSERT ((Port & 1) == 0);
127
128 Flag = FilterBeforeIoRead (FilterWidth16, Port, &Data);
129 if (Flag) {
130 if (IsTdxGuest ()) {
131 Data = TdIoRead16 (Port);
132 } else {
133 __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
134 }
135 }
136
137 FilterAfterIoRead (FilterWidth16, Port, &Data);
138
139 return Data;
140 }
141
142 /**
143 Writes a 16-bit I/O port.
144
145 Writes the 16-bit I/O port specified by Port with the value specified by Value
146 and returns Value. This function must guarantee that all I/O read and write
147 operations are serialized.
148
149 If 16-bit I/O port operations are not supported, then ASSERT().
150 If Port is not aligned on a 16-bit boundary, then ASSERT().
151
152 For Td guest TDVMCALL_IO is invoked to write I/O port.
153
154 @param Port The I/O port to write.
155 @param Value The value to write to the I/O port.
156
157 @return The value written the I/O port.
158
159 **/
160 UINT16
161 EFIAPI
162 IoWrite16 (
163 IN UINTN Port,
164 IN UINT16 Value
165 )
166 {
167 BOOLEAN Flag;
168
169 ASSERT ((Port & 1) == 0);
170
171 Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value);
172 if (Flag) {
173 if (IsTdxGuest ()) {
174 TdIoWrite16 (Port, Value);
175 } else {
176 __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
177 }
178 }
179
180 FilterAfterIoWrite (FilterWidth16, Port, &Value);
181
182 return Value;
183 }
184
185 /**
186 Reads a 32-bit I/O port.
187
188 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
189 This function must guarantee that all I/O read and write operations are
190 serialized.
191
192 If 32-bit I/O port operations are not supported, then ASSERT().
193 If Port is not aligned on a 32-bit boundary, then ASSERT().
194
195 For Td guest TDVMCALL_IO is invoked to read I/O port.
196
197 @param Port The I/O port to read.
198
199 @return The value read.
200
201 **/
202 UINT32
203 EFIAPI
204 IoRead32 (
205 IN UINTN Port
206 )
207 {
208 UINT32 Data;
209 BOOLEAN Flag;
210
211 ASSERT ((Port & 3) == 0);
212
213 Flag = FilterBeforeIoRead (FilterWidth32, Port, &Data);
214 if (Flag) {
215 if (IsTdxGuest ()) {
216 Data = TdIoRead32 (Port);
217 } else {
218 __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
219 }
220 }
221
222 FilterAfterIoRead (FilterWidth32, Port, &Data);
223
224 return Data;
225 }
226
227 /**
228 Writes a 32-bit I/O port.
229
230 Writes the 32-bit I/O port specified by Port with the value specified by Value
231 and returns Value. This function must guarantee that all I/O read and write
232 operations are serialized.
233
234 If 32-bit I/O port operations are not supported, then ASSERT().
235 If Port is not aligned on a 32-bit boundary, then ASSERT().
236
237 For Td guest TDVMCALL_IO is invoked to write I/O port.
238
239 @param Port The I/O port to write.
240 @param Value The value to write to the I/O port.
241
242 @return The value written the I/O port.
243
244 **/
245 UINT32
246 EFIAPI
247 IoWrite32 (
248 IN UINTN Port,
249 IN UINT32 Value
250 )
251 {
252 BOOLEAN Flag;
253
254 ASSERT ((Port & 3) == 0);
255
256 Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value);
257 if (Flag) {
258 if (IsTdxGuest ()) {
259 TdIoWrite32 (Port, Value);
260 } else {
261 __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
262 }
263 }
264
265 FilterAfterIoWrite (FilterWidth32, Port, &Value);
266
267 return Value;
268 }