]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
MdePkg/IoLib: Filter/trace port IO/MMIO access
[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
19 #include "BaseIoLibIntrinsicInternal.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 @param Port The I/O port to read.
31
32 @return The value read.
33
34 **/
35 UINT8
36 EFIAPI
37 IoRead8 (
38 IN UINTN Port
39 )
40 {
41 UINT8 Data;
42 BOOLEAN Flag;
43
44 Flag = FilterBeforeIoRead (FilterWidth8, Port, &Data);
45 if (Flag) {
46 __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
47 }
48 FilterAfterIoRead (FilterWidth8, Port, &Data);
49
50 return Data;
51 }
52
53 /**
54 Writes an 8-bit I/O port.
55
56 Writes the 8-bit I/O port specified by Port with the value specified by Value
57 and returns Value. This function must guarantee that all I/O read and write
58 operations are serialized.
59
60 If 8-bit I/O port operations are not supported, then ASSERT().
61
62 @param Port The I/O port to write.
63 @param Value The value to write to the I/O port.
64
65 @return The value written the I/O port.
66
67 **/
68 UINT8
69 EFIAPI
70 IoWrite8 (
71 IN UINTN Port,
72 IN UINT8 Value
73 )
74 {
75 BOOLEAN Flag;
76
77 Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value);
78 if (Flag) {
79 __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
80 }
81 FilterAfterIoWrite (FilterWidth8, Port, &Value);
82
83 return Value;;
84 }
85
86 /**
87 Reads a 16-bit I/O port.
88
89 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
90 This function must guarantee that all I/O read and write operations are
91 serialized.
92
93 If 16-bit I/O port operations are not supported, then ASSERT().
94 If Port is not aligned on a 16-bit boundary, then ASSERT().
95
96 @param Port The I/O port to read.
97
98 @return The value read.
99
100 **/
101 UINT16
102 EFIAPI
103 IoRead16 (
104 IN UINTN Port
105 )
106 {
107 UINT16 Data;
108 BOOLEAN Flag;
109
110 ASSERT ((Port & 1) == 0);
111
112 Flag = FilterBeforeIoRead (FilterWidth16, Port, &Data);
113 if (Flag) {
114 __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
115 }
116 FilterAfterIoRead (FilterWidth16, Port, &Data);
117
118 return Data;
119 }
120
121 /**
122 Writes a 16-bit I/O port.
123
124 Writes the 16-bit I/O port specified by Port with the value specified by Value
125 and returns Value. This function must guarantee that all I/O read and write
126 operations are serialized.
127
128 If 16-bit I/O port operations are not supported, then ASSERT().
129 If Port is not aligned on a 16-bit boundary, then ASSERT().
130
131 @param Port The I/O port to write.
132 @param Value The value to write to the I/O port.
133
134 @return The value written the I/O port.
135
136 **/
137 UINT16
138 EFIAPI
139 IoWrite16 (
140 IN UINTN Port,
141 IN UINT16 Value
142 )
143 {
144
145 BOOLEAN Flag;
146
147 ASSERT ((Port & 1) == 0);
148
149 Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value);
150 if (Flag) {
151 __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
152 }
153 FilterAfterIoWrite (FilterWidth16, Port, &Value);
154
155 return Value;;
156 }
157
158 /**
159 Reads a 32-bit I/O port.
160
161 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
162 This function must guarantee that all I/O read and write operations are
163 serialized.
164
165 If 32-bit I/O port operations are not supported, then ASSERT().
166 If Port is not aligned on a 32-bit boundary, then ASSERT().
167
168 @param Port The I/O port to read.
169
170 @return The value read.
171
172 **/
173 UINT32
174 EFIAPI
175 IoRead32 (
176 IN UINTN Port
177 )
178 {
179 UINT32 Data;
180 BOOLEAN Flag;
181
182 ASSERT ((Port & 3) == 0);
183
184 Flag = FilterBeforeIoRead (FilterWidth32, Port, &Data);
185 if (Flag) {
186 __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
187 }
188 FilterAfterIoRead (FilterWidth32, Port, &Data);
189
190 return Data;
191 }
192
193 /**
194 Writes a 32-bit I/O port.
195
196 Writes the 32-bit I/O port specified by Port with the value specified by Value
197 and returns Value. This function must guarantee that all I/O read and write
198 operations are serialized.
199
200 If 32-bit I/O port operations are not supported, then ASSERT().
201 If Port is not aligned on a 32-bit boundary, then ASSERT().
202
203 @param Port The I/O port to write.
204 @param Value The value to write to the I/O port.
205
206 @return The value written the I/O port.
207
208 **/
209 UINT32
210 EFIAPI
211 IoWrite32 (
212 IN UINTN Port,
213 IN UINT32 Value
214 )
215 {
216 BOOLEAN Flag;
217
218 ASSERT ((Port & 3) == 0);
219
220 Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value);
221 if (Flag) {
222 __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
223 }
224 FilterAfterIoWrite (FilterWidth32, Port, &Value);
225
226 return Value;
227 }
228