]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
MdePkg/IoLib: Filter/trace port IO/MMIO access
[mirror_edk2.git] / MdePkg / Library / BaseIoLibIntrinsic / IoLibGcc.c
CommitLineData
e1f414b6 1/** @file\r
2 I/O Library. This file has compiler specifics for GCC as there is no\r
3 ANSI C standard for doing IO.\r
4\r
5 GCC - uses EFIAPI assembler. __asm__ calls GAS. __volatile__ makes sure the\r
6 compiler puts the assembler in this exact location. The complex GNUC\r
7 operations are not optimzed. It would be possible to also write these\r
8 with EFIAPI assembler.\r
9\r
10 We don't advocate putting compiler specifics in libraries or drivers but there\r
11 is no other way to make this work.\r
12\r
38c8be12 13 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
9344f092 14 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 15\r
e1f414b6 16**/\r
17\r
1efcc4ae 18\r
f734a10a 19#include "BaseIoLibIntrinsicInternal.h"\r
e1f414b6 20\r
2281e7a9 21/**\r
22 Reads an 8-bit I/O port.\r
23\r
24 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.\r
25 This function must guarantee that all I/O read and write operations are\r
26 serialized.\r
27\r
28 If 8-bit I/O port operations are not supported, then ASSERT().\r
29\r
30 @param Port The I/O port to read.\r
31\r
32 @return The value read.\r
33\r
34**/\r
e1f414b6 35UINT8\r
36EFIAPI\r
37IoRead8 (\r
38 IN UINTN Port\r
39 )\r
40{\r
41 UINT8 Data;\r
38c8be12
DB
42 BOOLEAN Flag;\r
43\r
44 Flag = FilterBeforeIoRead (FilterWidth8, Port, &Data);\r
45 if (Flag) {\r
46 __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));\r
47 }\r
48 FilterAfterIoRead (FilterWidth8, Port, &Data);\r
e1f414b6 49\r
e1f414b6 50 return Data;\r
51}\r
52\r
2281e7a9 53/**\r
54 Writes an 8-bit I/O port.\r
55\r
56 Writes the 8-bit I/O port specified by Port with the value specified by Value\r
57 and returns Value. This function must guarantee that all I/O read and write\r
58 operations are serialized.\r
59\r
60 If 8-bit I/O port operations are not supported, then ASSERT().\r
61\r
62 @param Port The I/O port to write.\r
63 @param Value The value to write to the I/O port.\r
64\r
65 @return The value written the I/O port.\r
66\r
67**/\r
e1f414b6 68UINT8\r
69EFIAPI\r
70IoWrite8 (\r
71 IN UINTN Port,\r
72 IN UINT8 Value\r
73 )\r
74{\r
38c8be12
DB
75 BOOLEAN Flag;\r
76\r
77 Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value);\r
78 if (Flag) {\r
79 __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));\r
80 }\r
81 FilterAfterIoWrite (FilterWidth8, Port, &Value);\r
82\r
e1f414b6 83 return Value;;\r
84}\r
85\r
2281e7a9 86/**\r
87 Reads a 16-bit I/O port.\r
88\r
89 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.\r
90 This function must guarantee that all I/O read and write operations are\r
91 serialized.\r
92\r
93 If 16-bit I/O port operations are not supported, then ASSERT().\r
94 If Port is not aligned on a 16-bit boundary, then ASSERT().\r
95\r
96 @param Port The I/O port to read.\r
97\r
98 @return The value read.\r
99\r
100**/\r
e1f414b6 101UINT16\r
102EFIAPI\r
103IoRead16 (\r
104 IN UINTN Port\r
105 )\r
106{\r
107 UINT16 Data;\r
38c8be12 108 BOOLEAN Flag;\r
e1f414b6 109\r
110 ASSERT ((Port & 1) == 0);\r
38c8be12
DB
111\r
112 Flag = FilterBeforeIoRead (FilterWidth16, Port, &Data);\r
113 if (Flag) {\r
114 __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));\r
115 }\r
116 FilterAfterIoRead (FilterWidth16, Port, &Data);\r
117\r
e1f414b6 118 return Data;\r
119}\r
120\r
2281e7a9 121/**\r
122 Writes a 16-bit I/O port.\r
123\r
124 Writes the 16-bit I/O port specified by Port with the value specified by Value\r
125 and returns Value. This function must guarantee that all I/O read and write\r
126 operations are serialized.\r
127\r
128 If 16-bit I/O port operations are not supported, then ASSERT().\r
129 If Port is not aligned on a 16-bit boundary, then ASSERT().\r
9095d37b 130\r
2281e7a9 131 @param Port The I/O port to write.\r
132 @param Value The value to write to the I/O port.\r
133\r
134 @return The value written the I/O port.\r
135\r
136**/\r
e1f414b6 137UINT16\r
138EFIAPI\r
139IoWrite16 (\r
140 IN UINTN Port,\r
141 IN UINT16 Value\r
142 )\r
143{\r
38c8be12
DB
144\r
145 BOOLEAN Flag;\r
146\r
e1f414b6 147 ASSERT ((Port & 1) == 0);\r
38c8be12
DB
148\r
149 Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value);\r
150 if (Flag) {\r
151 __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));\r
152 }\r
153 FilterAfterIoWrite (FilterWidth16, Port, &Value);\r
154\r
e1f414b6 155 return Value;;\r
156}\r
157\r
2281e7a9 158/**\r
159 Reads a 32-bit I/O port.\r
160\r
161 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.\r
162 This function must guarantee that all I/O read and write operations are\r
163 serialized.\r
164\r
165 If 32-bit I/O port operations are not supported, then ASSERT().\r
166 If Port is not aligned on a 32-bit boundary, then ASSERT().\r
9095d37b 167\r
2281e7a9 168 @param Port The I/O port to read.\r
169\r
170 @return The value read.\r
171\r
172**/\r
e1f414b6 173UINT32\r
174EFIAPI\r
175IoRead32 (\r
176 IN UINTN Port\r
177 )\r
178{\r
179 UINT32 Data;\r
38c8be12 180 BOOLEAN Flag;\r
e1f414b6 181\r
182 ASSERT ((Port & 3) == 0);\r
38c8be12
DB
183\r
184 Flag = FilterBeforeIoRead (FilterWidth32, Port, &Data);\r
185 if (Flag) {\r
186 __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));\r
187 }\r
188 FilterAfterIoRead (FilterWidth32, Port, &Data);\r
189\r
e1f414b6 190 return Data;\r
191}\r
192\r
2281e7a9 193/**\r
194 Writes a 32-bit I/O port.\r
195\r
196 Writes the 32-bit I/O port specified by Port with the value specified by Value\r
197 and returns Value. This function must guarantee that all I/O read and write\r
198 operations are serialized.\r
199\r
200 If 32-bit I/O port operations are not supported, then ASSERT().\r
201 If Port is not aligned on a 32-bit boundary, then ASSERT().\r
9095d37b 202\r
2281e7a9 203 @param Port The I/O port to write.\r
204 @param Value The value to write to the I/O port.\r
205\r
206 @return The value written the I/O port.\r
207\r
208**/\r
e1f414b6 209UINT32\r
210EFIAPI\r
211IoWrite32 (\r
212 IN UINTN Port,\r
2281e7a9 213 IN UINT32 Value\r
e1f414b6 214 )\r
215{\r
38c8be12
DB
216 BOOLEAN Flag;\r
217\r
e1f414b6 218 ASSERT ((Port & 3) == 0);\r
38c8be12
DB
219\r
220 Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value);\r
221 if (Flag) {\r
222 __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));\r
223 }\r
224 FilterAfterIoWrite (FilterWidth32, Port, &Value);\r
225\r
e1f414b6 226 return Value;\r
227}\r
228\r