]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseIoLibIntrinsic / IoLibMsc.c
1 /** @file
2 I/O Library. This file has compiler specifics for Microsft C as there is no
3 ANSI C standard for doing IO.
4
5 MSC - uses intrinsic functions and the optimize will remove the function call
6 overhead.
7
8 We don't advocate putting compiler specifics in libraries or drivers but there
9 is no other way to make this work.
10
11 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
12 SPDX-License-Identifier: BSD-2-Clause-Patent
13
14 **/
15
16 #include "BaseIoLibIntrinsicInternal.h"
17 #include "IoLibTdx.h"
18
19 //
20 // Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
21 //
22
23 int
24 _inp (
25 unsigned short port
26 );
27
28 unsigned short
29 _inpw (
30 unsigned short port
31 );
32
33 unsigned long
34 _inpd (
35 unsigned short port
36 );
37
38 int
39 _outp (
40 unsigned short port,
41 int databyte
42 );
43
44 unsigned short
45 _outpw (
46 unsigned short port,
47 unsigned short dataword
48 );
49
50 unsigned long
51 _outpd (
52 unsigned short port,
53 unsigned long dataword
54 );
55
56 void
57 _ReadWriteBarrier (
58 void
59 );
60
61 #pragma intrinsic(_inp)
62 #pragma intrinsic(_inpw)
63 #pragma intrinsic(_inpd)
64 #pragma intrinsic(_outp)
65 #pragma intrinsic(_outpw)
66 #pragma intrinsic(_outpd)
67 #pragma intrinsic(_ReadWriteBarrier)
68
69 //
70 // _ReadWriteBarrier() forces memory reads and writes to complete at the point
71 // in the call. This is only a hint to the compiler and does emit code.
72 // In past versions of the compiler, _ReadWriteBarrier was enforced only
73 // locally and did not affect functions up the call tree. In Visual C++
74 // 2005, _ReadWriteBarrier is enforced all the way up the call tree.
75 //
76
77 /**
78 Reads an 8-bit I/O port.
79
80 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
81 This function must guarantee that all I/O read and write operations are
82 serialized.
83
84 If 8-bit I/O port operations are not supported, then ASSERT().
85
86 For Td guest TDVMCALL_IO is invoked to read I/O port.
87
88 @param Port The I/O port to read.
89
90 @return The value read.
91
92 **/
93 UINT8
94 EFIAPI
95 IoRead8 (
96 IN UINTN Port
97 )
98 {
99 UINT8 Value;
100 BOOLEAN Flag;
101
102 Flag = FilterBeforeIoRead (FilterWidth8, Port, &Value);
103 if (Flag) {
104 if (IsTdxGuest ()) {
105 Value = TdIoRead8 (Port);
106 } else {
107 _ReadWriteBarrier ();
108 Value = (UINT8)_inp ((UINT16)Port);
109 _ReadWriteBarrier ();
110 }
111 }
112
113 FilterAfterIoRead (FilterWidth8, Port, &Value);
114
115 return Value;
116 }
117
118 /**
119 Writes an 8-bit I/O port.
120
121 Writes the 8-bit I/O port specified by Port with the value specified by Value
122 and returns Value. This function must guarantee that all I/O read and write
123 operations are serialized.
124
125 If 8-bit I/O port operations are not supported, then ASSERT().
126
127 For Td guest TDVMCALL_IO is invoked to write I/O port.
128
129 @param Port The I/O port to write.
130 @param Value The value to write to the I/O port.
131
132 @return The value written to the I/O port.
133
134 **/
135 UINT8
136 EFIAPI
137 IoWrite8 (
138 IN UINTN Port,
139 IN UINT8 Value
140 )
141 {
142 BOOLEAN Flag;
143
144 Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value);
145 if (Flag) {
146 if (IsTdxGuest ()) {
147 TdIoWrite8 (Port, Value);
148 } else {
149 _ReadWriteBarrier ();
150 (UINT8)_outp ((UINT16)Port, Value);
151 _ReadWriteBarrier ();
152 }
153 }
154
155 FilterAfterIoWrite (FilterWidth8, Port, &Value);
156
157 return Value;
158 }
159
160 /**
161 Reads a 16-bit I/O port.
162
163 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
164 This function must guarantee that all I/O read and write operations are
165 serialized.
166
167 If 16-bit I/O port operations are not supported, then ASSERT().
168 If Port is not aligned on a 16-bit boundary, then ASSERT().
169
170 For Td guest TDVMCALL_IO is invoked to read I/O port.
171
172 @param Port The I/O port to read.
173
174 @return The value read.
175
176 **/
177 UINT16
178 EFIAPI
179 IoRead16 (
180 IN UINTN Port
181 )
182 {
183 UINT16 Value;
184 BOOLEAN Flag;
185
186 ASSERT ((Port & 1) == 0);
187
188 Flag = FilterBeforeIoRead (FilterWidth16, Port, &Value);
189 if (Flag) {
190 if (IsTdxGuest ()) {
191 Value = TdIoRead16 (Port);
192 } else {
193 _ReadWriteBarrier ();
194 Value = _inpw ((UINT16)Port);
195 _ReadWriteBarrier ();
196 }
197 }
198
199 FilterBeforeIoRead (FilterWidth16, Port, &Value);
200
201 return Value;
202 }
203
204 /**
205 Writes a 16-bit I/O port.
206
207 Writes the 16-bit I/O port specified by Port with the value specified by Value
208 and returns Value. This function must guarantee that all I/O read and write
209 operations are serialized.
210
211 If 16-bit I/O port operations are not supported, then ASSERT().
212 If Port is not aligned on a 16-bit boundary, then ASSERT().
213
214 For Td guest TDVMCALL_IO is invoked to write I/O port.
215
216 @param Port The I/O port to write.
217 @param Value The value to write to the I/O port.
218
219 @return The value written to the I/O port.
220
221 **/
222 UINT16
223 EFIAPI
224 IoWrite16 (
225 IN UINTN Port,
226 IN UINT16 Value
227 )
228 {
229 BOOLEAN Flag;
230
231 ASSERT ((Port & 1) == 0);
232
233 Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value);
234 if (Flag) {
235 if (IsTdxGuest ()) {
236 TdIoWrite16 (Port, Value);
237 } else {
238 _ReadWriteBarrier ();
239 _outpw ((UINT16)Port, Value);
240 _ReadWriteBarrier ();
241 }
242 }
243
244 FilterAfterIoWrite (FilterWidth16, Port, &Value);
245
246 return Value;
247 }
248
249 /**
250 Reads a 32-bit I/O port.
251
252 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
253 This function must guarantee that all I/O read and write operations are
254 serialized.
255
256 If 32-bit I/O port operations are not supported, then ASSERT().
257 If Port is not aligned on a 32-bit boundary, then ASSERT().
258
259 For Td guest TDVMCALL_IO is invoked to read I/O port.
260
261 @param Port The I/O port to read.
262
263 @return The value read.
264
265 **/
266 UINT32
267 EFIAPI
268 IoRead32 (
269 IN UINTN Port
270 )
271 {
272 UINT32 Value;
273 BOOLEAN Flag;
274
275 ASSERT ((Port & 3) == 0);
276
277 Flag = FilterBeforeIoRead (FilterWidth32, Port, &Value);
278 if (Flag) {
279 if (IsTdxGuest ()) {
280 Value = TdIoRead32 (Port);
281 } else {
282 _ReadWriteBarrier ();
283 Value = _inpd ((UINT16)Port);
284 _ReadWriteBarrier ();
285 }
286 }
287
288 FilterAfterIoRead (FilterWidth32, Port, &Value);
289
290 return Value;
291 }
292
293 /**
294 Writes a 32-bit I/O port.
295
296 Writes the 32-bit I/O port specified by Port with the value specified by Value
297 and returns Value. This function must guarantee that all I/O read and write
298 operations are serialized.
299
300 If 32-bit I/O port operations are not supported, then ASSERT().
301 If Port is not aligned on a 32-bit boundary, then ASSERT().
302
303 For Td guest TDVMCALL_IO is invoked to write I/O port.
304
305 @param Port The I/O port to write.
306 @param Value The value to write to the I/O port.
307
308 @return The value written to the I/O port.
309
310 **/
311 UINT32
312 EFIAPI
313 IoWrite32 (
314 IN UINTN Port,
315 IN UINT32 Value
316 )
317 {
318 BOOLEAN Flag;
319
320 ASSERT ((Port & 3) == 0);
321
322 Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value);
323 if (Flag) {
324 if (IsTdxGuest ()) {
325 TdIoWrite32 (Port, Value);
326 } else {
327 _ReadWriteBarrier ();
328 _outpd ((UINT16)Port, Value);
329 _ReadWriteBarrier ();
330 }
331 }
332
333 FilterAfterIoWrite (FilterWidth32, Port, &Value);
334
335 return Value;
336 }