]>
Commit | Line | Data |
---|---|---|
e1f414b6 | 1 | /** @file\r |
5c57f3ea | 2 | PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.\r |
3 | Layers on top of an I/O Library instance.\r | |
e1f414b6 | 4 | \r |
9095d37b | 5 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r |
9344f092 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
e1f414b6 | 7 | \r |
e1f414b6 | 8 | **/\r |
9 | \r | |
c892d846 | 10 | \r |
c7d265a9 | 11 | #include <Base.h>\r |
c892d846 | 12 | \r |
0c62737d | 13 | #include <Library/BaseLib.h>\r |
c7d265a9 | 14 | #include <Library/PciCf8Lib.h>\r |
15 | #include <Library/IoLib.h>\r | |
16 | #include <Library/DebugLib.h>\r | |
e1f414b6 | 17 | \r |
18 | //\r | |
19 | // Declare I/O Ports used to perform PCI Confguration Cycles\r | |
20 | //\r | |
21 | #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8\r | |
22 | #define PCI_CONFIGURATION_DATA_PORT 0xCFC\r | |
23 | \r | |
e1f414b6 | 24 | /**\r |
ad400b07 | 25 | Convert a PCI Library address to PCI CF8 formatted address.\r |
26 | \r | |
27 | Declare macro to convert PCI Library address to PCI CF8 formatted address.\r | |
28 | Bit fields of PCI Library and CF8 formatted address is as follows:\r | |
29 | PCI Library formatted address CF8 Formatted Address\r | |
30 | ============================= ======================\r | |
31 | Bits 00..11 Register Bits 00..07 Register\r | |
32 | Bits 12..14 Function Bits 08..10 Function\r | |
33 | Bits 15..19 Device Bits 11..15 Device\r | |
34 | Bits 20..27 Bus Bits 16..23 Bus\r | |
35 | Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)\r | |
36 | Bits 31..31 Must be 1\r | |
e1f414b6 | 37 | \r |
38 | @param A The address to convert.\r | |
39 | \r | |
40 | @retval The coverted address.\r | |
41 | \r | |
42 | **/\r | |
43 | #define PCI_TO_CF8_ADDRESS(A) \\r | |
44 | ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))\r | |
45 | \r | |
ad400b07 | 46 | /**\r |
47 | Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's\r | |
48 | only in the low 28 bits, excluding bits 08..11.\r | |
49 | \r | |
50 | @param A The address to validate.\r | |
51 | @param M Additional bits to assert to be zero.\r | |
52 | \r | |
53 | **/\r | |
54 | #define ASSERT_INVALID_PCI_ADDRESS(A,M) \\r | |
55 | ASSERT (((A) & (~0xffff0ff | (M))) == 0)\r | |
56 | \r | |
3e3ae634 | 57 | /**\r |
9095d37b | 58 | Registers a PCI device so PCI configuration registers may be accessed after\r |
3e3ae634 | 59 | SetVirtualAddressMap().\r |
9095d37b LG |
60 | \r |
61 | Registers the PCI device specified by Address so all the PCI configuration registers\r | |
d11195a3 | 62 | associated with that PCI device may be accessed after SetVirtualAddressMap() is called.\r |
9095d37b | 63 | \r |
3e3ae634 | 64 | If Address > 0x0FFFFFFF, then ASSERT().\r |
59ceeabe | 65 | If the register specified by Address >= 0x100, then ASSERT().\r |
3e3ae634 | 66 | \r |
2fc59a00 | 67 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
3e3ae634 | 68 | Register.\r |
9095d37b | 69 | \r |
3e3ae634 | 70 | @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r |
9095d37b | 71 | @retval RETURN_UNSUPPORTED An attempt was made to call this function\r |
3e3ae634 | 72 | after ExitBootServices().\r |
73 | @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r | |
74 | at runtime could not be mapped.\r | |
75 | @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r | |
76 | complete the registration.\r | |
77 | \r | |
78 | **/\r | |
79 | RETURN_STATUS\r | |
80 | EFIAPI\r | |
81 | PciCf8RegisterForRuntimeAccess (\r | |
82 | IN UINTN Address\r | |
83 | )\r | |
84 | {\r | |
59ceeabe | 85 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
3e3ae634 | 86 | return RETURN_SUCCESS;\r |
87 | }\r | |
88 | \r | |
e1f414b6 | 89 | /**\r |
90 | Reads an 8-bit PCI configuration register.\r | |
91 | \r | |
92 | Reads and returns the 8-bit PCI configuration register specified by Address.\r | |
93 | This function must guarantee that all PCI read and write operations are\r | |
94 | serialized.\r | |
95 | \r | |
96 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
97 | If the register specified by Address >= 0x100, then ASSERT().\r | |
98 | \r | |
2fc59a00 | 99 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 100 | Register.\r |
101 | \r | |
102 | @return The read value from the PCI configuration register.\r | |
103 | \r | |
104 | **/\r | |
105 | UINT8\r | |
106 | EFIAPI\r | |
107 | PciCf8Read8 (\r | |
108 | IN UINTN Address\r | |
109 | )\r | |
110 | {\r | |
96dd57ee | 111 | BOOLEAN InterruptState;\r |
112 | UINT32 AddressPort;\r | |
113 | UINT8 Result;\r | |
9095d37b | 114 | \r |
e1f414b6 | 115 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 116 | InterruptState = SaveAndDisableInterrupts ();\r |
117 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 118 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 119 | Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));\r |
120 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
121 | SetInterruptState (InterruptState);\r | |
122 | return Result;\r | |
e1f414b6 | 123 | }\r |
124 | \r | |
125 | /**\r | |
126 | Writes an 8-bit PCI configuration register.\r | |
127 | \r | |
128 | Writes the 8-bit PCI configuration register specified by Address with the\r | |
129 | value specified by Value. Value is returned. This function must guarantee\r | |
130 | that all PCI read and write operations are serialized.\r | |
131 | \r | |
132 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
133 | If the register specified by Address >= 0x100, then ASSERT().\r | |
134 | \r | |
2fc59a00 | 135 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 136 | Register.\r |
137 | @param Value The value to write.\r | |
138 | \r | |
139 | @return The value written to the PCI configuration register.\r | |
140 | \r | |
141 | **/\r | |
142 | UINT8\r | |
143 | EFIAPI\r | |
144 | PciCf8Write8 (\r | |
145 | IN UINTN Address,\r | |
146 | IN UINT8 Value\r | |
147 | )\r | |
148 | {\r | |
96dd57ee | 149 | BOOLEAN InterruptState;\r |
150 | UINT32 AddressPort;\r | |
151 | UINT8 Result;\r | |
9095d37b | 152 | \r |
e1f414b6 | 153 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 154 | InterruptState = SaveAndDisableInterrupts ();\r |
155 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 156 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 157 | Result = IoWrite8 (\r |
158 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
159 | Value\r | |
160 | );\r | |
161 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
162 | SetInterruptState (InterruptState);\r | |
163 | return Result;\r | |
e1f414b6 | 164 | }\r |
165 | \r | |
166 | /**\r | |
62991af2 | 167 | Performs a bitwise OR of an 8-bit PCI configuration register with\r |
e1f414b6 | 168 | an 8-bit value.\r |
169 | \r | |
170 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 171 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 172 | OrData, and writes the result to the 8-bit PCI configuration register\r |
173 | specified by Address. The value written to the PCI configuration register is\r | |
174 | returned. This function must guarantee that all PCI read and write operations\r | |
175 | are serialized.\r | |
176 | \r | |
177 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
178 | If the register specified by Address >= 0x100, then ASSERT().\r | |
179 | \r | |
2fc59a00 | 180 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 181 | Register.\r |
182 | @param OrData The value to OR with the PCI configuration register.\r | |
183 | \r | |
184 | @return The value written back to the PCI configuration register.\r | |
185 | \r | |
186 | **/\r | |
187 | UINT8\r | |
188 | EFIAPI\r | |
189 | PciCf8Or8 (\r | |
190 | IN UINTN Address,\r | |
191 | IN UINT8 OrData\r | |
192 | )\r | |
193 | {\r | |
96dd57ee | 194 | BOOLEAN InterruptState;\r |
195 | UINT32 AddressPort;\r | |
196 | UINT8 Result;\r | |
9095d37b | 197 | \r |
e1f414b6 | 198 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 199 | InterruptState = SaveAndDisableInterrupts ();\r |
200 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 201 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 202 | Result = IoOr8 (\r |
203 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
204 | OrData\r | |
205 | );\r | |
206 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
207 | SetInterruptState (InterruptState);\r | |
208 | return Result;\r | |
e1f414b6 | 209 | }\r |
210 | \r | |
211 | /**\r | |
212 | Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r | |
213 | value.\r | |
214 | \r | |
215 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
216 | bitwise AND between the read result and the value specified by AndData, and\r | |
217 | writes the result to the 8-bit PCI configuration register specified by\r | |
218 | Address. The value written to the PCI configuration register is returned.\r | |
219 | This function must guarantee that all PCI read and write operations are\r | |
220 | serialized.\r | |
221 | \r | |
222 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
223 | If the register specified by Address >= 0x100, then ASSERT().\r | |
224 | \r | |
2fc59a00 | 225 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 226 | Register.\r |
227 | @param AndData The value to AND with the PCI configuration register.\r | |
228 | \r | |
229 | @return The value written back to the PCI configuration register.\r | |
230 | \r | |
231 | **/\r | |
232 | UINT8\r | |
233 | EFIAPI\r | |
234 | PciCf8And8 (\r | |
235 | IN UINTN Address,\r | |
236 | IN UINT8 AndData\r | |
237 | )\r | |
238 | {\r | |
96dd57ee | 239 | BOOLEAN InterruptState;\r |
240 | UINT32 AddressPort;\r | |
241 | UINT8 Result;\r | |
9095d37b | 242 | \r |
e1f414b6 | 243 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 244 | InterruptState = SaveAndDisableInterrupts ();\r |
245 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 246 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 247 | Result = IoAnd8 (\r |
248 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
249 | AndData\r | |
250 | );\r | |
251 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
252 | SetInterruptState (InterruptState);\r | |
253 | return Result;\r | |
e1f414b6 | 254 | }\r |
255 | \r | |
256 | /**\r | |
257 | Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r | |
62991af2 | 258 | value, followed a bitwise OR with another 8-bit value.\r |
e1f414b6 | 259 | \r |
260 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
261 | bitwise AND between the read result and the value specified by AndData,\r | |
62991af2 | 262 | performs a bitwise OR between the result of the AND operation and\r |
e1f414b6 | 263 | the value specified by OrData, and writes the result to the 8-bit PCI\r |
264 | configuration register specified by Address. The value written to the PCI\r | |
265 | configuration register is returned. This function must guarantee that all PCI\r | |
266 | read and write operations are serialized.\r | |
267 | \r | |
268 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
269 | If the register specified by Address >= 0x100, then ASSERT().\r | |
270 | \r | |
2fc59a00 | 271 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 272 | Register.\r |
273 | @param AndData The value to AND with the PCI configuration register.\r | |
274 | @param OrData The value to OR with the result of the AND operation.\r | |
275 | \r | |
276 | @return The value written back to the PCI configuration register.\r | |
277 | \r | |
278 | **/\r | |
279 | UINT8\r | |
280 | EFIAPI\r | |
281 | PciCf8AndThenOr8 (\r | |
282 | IN UINTN Address,\r | |
283 | IN UINT8 AndData,\r | |
284 | IN UINT8 OrData\r | |
285 | )\r | |
286 | {\r | |
96dd57ee | 287 | BOOLEAN InterruptState;\r |
288 | UINT32 AddressPort;\r | |
289 | UINT8 Result;\r | |
9095d37b | 290 | \r |
e1f414b6 | 291 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 292 | InterruptState = SaveAndDisableInterrupts ();\r |
293 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 294 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 295 | Result = IoAndThenOr8 (\r |
296 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
297 | AndData,\r | |
298 | OrData\r | |
299 | );\r | |
300 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
301 | SetInterruptState (InterruptState);\r | |
302 | return Result;\r | |
e1f414b6 | 303 | }\r |
304 | \r | |
305 | /**\r | |
306 | Reads a bit field of a PCI configuration register.\r | |
307 | \r | |
308 | Reads the bit field in an 8-bit PCI configuration register. The bit field is\r | |
309 | specified by the StartBit and the EndBit. The value of the bit field is\r | |
310 | returned.\r | |
311 | \r | |
312 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
313 | If the register specified by Address >= 0x100, then ASSERT().\r | |
314 | If StartBit is greater than 7, then ASSERT().\r | |
315 | If EndBit is greater than 7, then ASSERT().\r | |
316 | If EndBit is less than StartBit, then ASSERT().\r | |
317 | \r | |
2fc59a00 | 318 | @param Address The PCI configuration register to read.\r |
e1f414b6 | 319 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
320 | Range 0..7.\r | |
321 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
322 | Range 0..7.\r | |
323 | \r | |
324 | @return The value of the bit field read from the PCI configuration register.\r | |
325 | \r | |
326 | **/\r | |
327 | UINT8\r | |
328 | EFIAPI\r | |
329 | PciCf8BitFieldRead8 (\r | |
330 | IN UINTN Address,\r | |
331 | IN UINTN StartBit,\r | |
332 | IN UINTN EndBit\r | |
333 | )\r | |
334 | {\r | |
96dd57ee | 335 | BOOLEAN InterruptState;\r |
336 | UINT32 AddressPort;\r | |
337 | UINT8 Result;\r | |
9095d37b | 338 | \r |
e1f414b6 | 339 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 340 | InterruptState = SaveAndDisableInterrupts ();\r |
341 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 342 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 343 | Result = IoBitFieldRead8 (\r |
344 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
345 | StartBit,\r | |
346 | EndBit\r | |
347 | );\r | |
348 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
349 | SetInterruptState (InterruptState);\r | |
350 | return Result;\r | |
e1f414b6 | 351 | }\r |
352 | \r | |
353 | /**\r | |
354 | Writes a bit field to a PCI configuration register.\r | |
355 | \r | |
356 | Writes Value to the bit field of the PCI configuration register. The bit\r | |
357 | field is specified by the StartBit and the EndBit. All other bits in the\r | |
358 | destination PCI configuration register are preserved. The new value of the\r | |
359 | 8-bit register is returned.\r | |
360 | \r | |
361 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
362 | If the register specified by Address >= 0x100, then ASSERT().\r | |
363 | If StartBit is greater than 7, then ASSERT().\r | |
364 | If EndBit is greater than 7, then ASSERT().\r | |
365 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 366 | If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 367 | \r |
2fc59a00 | 368 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 369 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
370 | Range 0..7.\r | |
371 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
372 | Range 0..7.\r | |
2fc59a00 | 373 | @param Value The new value of the bit field.\r |
e1f414b6 | 374 | \r |
375 | @return The value written back to the PCI configuration register.\r | |
376 | \r | |
377 | **/\r | |
378 | UINT8\r | |
379 | EFIAPI\r | |
380 | PciCf8BitFieldWrite8 (\r | |
381 | IN UINTN Address,\r | |
382 | IN UINTN StartBit,\r | |
383 | IN UINTN EndBit,\r | |
384 | IN UINT8 Value\r | |
385 | )\r | |
386 | {\r | |
96dd57ee | 387 | BOOLEAN InterruptState;\r |
388 | UINT32 AddressPort;\r | |
389 | UINT8 Result;\r | |
9095d37b | 390 | \r |
e1f414b6 | 391 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 392 | InterruptState = SaveAndDisableInterrupts ();\r |
393 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 394 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 395 | Result = IoBitFieldWrite8 (\r |
396 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
397 | StartBit,\r | |
398 | EndBit,\r | |
399 | Value\r | |
400 | );\r | |
401 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
402 | SetInterruptState (InterruptState);\r | |
403 | return Result;\r | |
e1f414b6 | 404 | }\r |
405 | \r | |
406 | /**\r | |
407 | Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r | |
408 | writes the result back to the bit field in the 8-bit port.\r | |
409 | \r | |
410 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 411 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 412 | OrData, and writes the result to the 8-bit PCI configuration register\r |
413 | specified by Address. The value written to the PCI configuration register is\r | |
414 | returned. This function must guarantee that all PCI read and write operations\r | |
415 | are serialized. Extra left bits in OrData are stripped.\r | |
416 | \r | |
417 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
418 | If the register specified by Address >= 0x100, then ASSERT().\r | |
419 | If StartBit is greater than 7, then ASSERT().\r | |
420 | If EndBit is greater than 7, then ASSERT().\r | |
421 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 422 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 423 | \r |
2fc59a00 | 424 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 425 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
426 | Range 0..7.\r | |
427 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
428 | Range 0..7.\r | |
429 | @param OrData The value to OR with the PCI configuration register.\r | |
430 | \r | |
431 | @return The value written back to the PCI configuration register.\r | |
432 | \r | |
433 | **/\r | |
434 | UINT8\r | |
435 | EFIAPI\r | |
436 | PciCf8BitFieldOr8 (\r | |
437 | IN UINTN Address,\r | |
438 | IN UINTN StartBit,\r | |
439 | IN UINTN EndBit,\r | |
440 | IN UINT8 OrData\r | |
441 | )\r | |
442 | {\r | |
96dd57ee | 443 | BOOLEAN InterruptState;\r |
444 | UINT32 AddressPort;\r | |
445 | UINT8 Result;\r | |
9095d37b | 446 | \r |
e1f414b6 | 447 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 448 | InterruptState = SaveAndDisableInterrupts ();\r |
449 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 450 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 451 | Result = IoBitFieldOr8 (\r |
452 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
453 | StartBit,\r | |
454 | EndBit,\r | |
455 | OrData\r | |
456 | );\r | |
457 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
458 | SetInterruptState (InterruptState);\r | |
459 | return Result;\r | |
e1f414b6 | 460 | }\r |
461 | \r | |
462 | /**\r | |
463 | Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r | |
464 | AND, and writes the result back to the bit field in the 8-bit register.\r | |
465 | \r | |
466 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
467 | bitwise AND between the read result and the value specified by AndData, and\r | |
468 | writes the result to the 8-bit PCI configuration register specified by\r | |
469 | Address. The value written to the PCI configuration register is returned.\r | |
470 | This function must guarantee that all PCI read and write operations are\r | |
471 | serialized. Extra left bits in AndData are stripped.\r | |
472 | \r | |
473 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
474 | If the register specified by Address >= 0x100, then ASSERT().\r | |
475 | If StartBit is greater than 7, then ASSERT().\r | |
476 | If EndBit is greater than 7, then ASSERT().\r | |
477 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 478 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 479 | \r |
2fc59a00 | 480 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 481 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
482 | Range 0..7.\r | |
483 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
484 | Range 0..7.\r | |
485 | @param AndData The value to AND with the PCI configuration register.\r | |
486 | \r | |
487 | @return The value written back to the PCI configuration register.\r | |
488 | \r | |
489 | **/\r | |
490 | UINT8\r | |
491 | EFIAPI\r | |
492 | PciCf8BitFieldAnd8 (\r | |
493 | IN UINTN Address,\r | |
494 | IN UINTN StartBit,\r | |
495 | IN UINTN EndBit,\r | |
496 | IN UINT8 AndData\r | |
497 | )\r | |
498 | {\r | |
96dd57ee | 499 | BOOLEAN InterruptState;\r |
500 | UINT32 AddressPort;\r | |
501 | UINT8 Result;\r | |
9095d37b | 502 | \r |
e1f414b6 | 503 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 504 | InterruptState = SaveAndDisableInterrupts ();\r |
505 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 506 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 507 | Result = IoBitFieldAnd8 (\r |
508 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
509 | StartBit,\r | |
510 | EndBit,\r | |
511 | AndData\r | |
512 | );\r | |
513 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
514 | SetInterruptState (InterruptState);\r | |
515 | return Result;\r | |
e1f414b6 | 516 | }\r |
517 | \r | |
518 | /**\r | |
519 | Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r | |
62991af2 | 520 | bitwise OR, and writes the result back to the bit field in the\r |
e1f414b6 | 521 | 8-bit port.\r |
522 | \r | |
523 | Reads the 8-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 524 | bitwise AND followed by a bitwise OR between the read result and\r |
e1f414b6 | 525 | the value specified by AndData, and writes the result to the 8-bit PCI\r |
526 | configuration register specified by Address. The value written to the PCI\r | |
527 | configuration register is returned. This function must guarantee that all PCI\r | |
528 | read and write operations are serialized. Extra left bits in both AndData and\r | |
529 | OrData are stripped.\r | |
530 | \r | |
531 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
532 | If the register specified by Address >= 0x100, then ASSERT().\r | |
533 | If StartBit is greater than 7, then ASSERT().\r | |
534 | If EndBit is greater than 7, then ASSERT().\r | |
535 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 LG |
536 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
537 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r | |
e1f414b6 | 538 | \r |
2fc59a00 | 539 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 540 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
541 | Range 0..7.\r | |
542 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
543 | Range 0..7.\r | |
544 | @param AndData The value to AND with the PCI configuration register.\r | |
545 | @param OrData The value to OR with the result of the AND operation.\r | |
546 | \r | |
547 | @return The value written back to the PCI configuration register.\r | |
548 | \r | |
549 | **/\r | |
550 | UINT8\r | |
551 | EFIAPI\r | |
552 | PciCf8BitFieldAndThenOr8(\r | |
553 | IN UINTN Address,\r | |
554 | IN UINTN StartBit,\r | |
555 | IN UINTN EndBit,\r | |
556 | IN UINT8 AndData,\r | |
557 | IN UINT8 OrData\r | |
558 | )\r | |
559 | {\r | |
96dd57ee | 560 | BOOLEAN InterruptState;\r |
561 | UINT32 AddressPort;\r | |
562 | UINT8 Result;\r | |
9095d37b | 563 | \r |
e1f414b6 | 564 | ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r |
96dd57ee | 565 | InterruptState = SaveAndDisableInterrupts ();\r |
566 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 567 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 568 | Result = IoBitFieldAndThenOr8 (\r |
569 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r | |
570 | StartBit,\r | |
571 | EndBit,\r | |
572 | AndData,\r | |
573 | OrData\r | |
574 | );\r | |
575 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
576 | SetInterruptState (InterruptState);\r | |
577 | return Result;\r | |
e1f414b6 | 578 | }\r |
579 | \r | |
580 | /**\r | |
581 | Reads a 16-bit PCI configuration register.\r | |
582 | \r | |
583 | Reads and returns the 16-bit PCI configuration register specified by Address.\r | |
584 | This function must guarantee that all PCI read and write operations are\r | |
585 | serialized.\r | |
586 | \r | |
587 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
588 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
589 | If the register specified by Address >= 0x100, then ASSERT().\r | |
590 | \r | |
2fc59a00 | 591 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 592 | Register.\r |
593 | \r | |
594 | @return The read value from the PCI configuration register.\r | |
595 | \r | |
596 | **/\r | |
597 | UINT16\r | |
598 | EFIAPI\r | |
599 | PciCf8Read16 (\r | |
600 | IN UINTN Address\r | |
601 | )\r | |
602 | {\r | |
96dd57ee | 603 | BOOLEAN InterruptState;\r |
604 | UINT32 AddressPort;\r | |
605 | UINT16 Result;\r | |
9095d37b | 606 | \r |
e1f414b6 | 607 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 608 | InterruptState = SaveAndDisableInterrupts ();\r |
609 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 610 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 611 | Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));\r |
612 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
613 | SetInterruptState (InterruptState);\r | |
614 | return Result;\r | |
e1f414b6 | 615 | }\r |
616 | \r | |
617 | /**\r | |
618 | Writes a 16-bit PCI configuration register.\r | |
619 | \r | |
620 | Writes the 16-bit PCI configuration register specified by Address with the\r | |
621 | value specified by Value. Value is returned. This function must guarantee\r | |
622 | that all PCI read and write operations are serialized.\r | |
623 | \r | |
624 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
625 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
626 | If the register specified by Address >= 0x100, then ASSERT().\r | |
627 | \r | |
2fc59a00 | 628 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 629 | Register.\r |
630 | @param Value The value to write.\r | |
631 | \r | |
632 | @return The value written to the PCI configuration register.\r | |
633 | \r | |
634 | **/\r | |
635 | UINT16\r | |
636 | EFIAPI\r | |
637 | PciCf8Write16 (\r | |
638 | IN UINTN Address,\r | |
639 | IN UINT16 Value\r | |
640 | )\r | |
641 | {\r | |
96dd57ee | 642 | BOOLEAN InterruptState;\r |
643 | UINT32 AddressPort;\r | |
644 | UINT16 Result;\r | |
9095d37b | 645 | \r |
e1f414b6 | 646 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 647 | InterruptState = SaveAndDisableInterrupts ();\r |
648 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 649 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 650 | Result = IoWrite16 (\r |
651 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
652 | Value\r | |
653 | );\r | |
654 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
655 | SetInterruptState (InterruptState);\r | |
656 | return Result;\r | |
e1f414b6 | 657 | }\r |
658 | \r | |
659 | /**\r | |
62991af2 | 660 | Performs a bitwise OR of a 16-bit PCI configuration register with\r |
e1f414b6 | 661 | a 16-bit value.\r |
662 | \r | |
663 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 664 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 665 | OrData, and writes the result to the 16-bit PCI configuration register\r |
666 | specified by Address. The value written to the PCI configuration register is\r | |
667 | returned. This function must guarantee that all PCI read and write operations\r | |
668 | are serialized.\r | |
669 | \r | |
670 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
671 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
672 | If the register specified by Address >= 0x100, then ASSERT().\r | |
673 | \r | |
2fc59a00 | 674 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 675 | Register.\r |
676 | @param OrData The value to OR with the PCI configuration register.\r | |
677 | \r | |
678 | @return The value written back to the PCI configuration register.\r | |
679 | \r | |
680 | **/\r | |
681 | UINT16\r | |
682 | EFIAPI\r | |
683 | PciCf8Or16 (\r | |
684 | IN UINTN Address,\r | |
685 | IN UINT16 OrData\r | |
686 | )\r | |
687 | {\r | |
96dd57ee | 688 | BOOLEAN InterruptState;\r |
689 | UINT32 AddressPort;\r | |
690 | UINT16 Result;\r | |
9095d37b | 691 | \r |
e1f414b6 | 692 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 693 | InterruptState = SaveAndDisableInterrupts ();\r |
694 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 695 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 696 | Result = IoOr16 (\r |
697 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
698 | OrData\r | |
699 | );\r | |
700 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
701 | SetInterruptState (InterruptState);\r | |
702 | return Result;\r | |
e1f414b6 | 703 | }\r |
704 | \r | |
705 | /**\r | |
706 | Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r | |
707 | value.\r | |
708 | \r | |
709 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
710 | bitwise AND between the read result and the value specified by AndData, and\r | |
711 | writes the result to the 16-bit PCI configuration register specified by\r | |
712 | Address. The value written to the PCI configuration register is returned.\r | |
713 | This function must guarantee that all PCI read and write operations are\r | |
714 | serialized.\r | |
715 | \r | |
716 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
717 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
718 | If the register specified by Address >= 0x100, then ASSERT().\r | |
719 | \r | |
2fc59a00 | 720 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 721 | Register.\r |
722 | @param AndData The value to AND with the PCI configuration register.\r | |
723 | \r | |
724 | @return The value written back to the PCI configuration register.\r | |
725 | \r | |
726 | **/\r | |
727 | UINT16\r | |
728 | EFIAPI\r | |
729 | PciCf8And16 (\r | |
730 | IN UINTN Address,\r | |
731 | IN UINT16 AndData\r | |
732 | )\r | |
733 | {\r | |
96dd57ee | 734 | BOOLEAN InterruptState;\r |
735 | UINT32 AddressPort;\r | |
736 | UINT16 Result;\r | |
9095d37b | 737 | \r |
e1f414b6 | 738 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 739 | InterruptState = SaveAndDisableInterrupts ();\r |
740 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 741 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 742 | Result = IoAnd16 (\r |
743 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
744 | AndData\r | |
745 | );\r | |
746 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
747 | SetInterruptState (InterruptState);\r | |
748 | return Result;\r | |
e1f414b6 | 749 | }\r |
750 | \r | |
751 | /**\r | |
752 | Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r | |
62991af2 | 753 | value, followed a bitwise OR with another 16-bit value.\r |
e1f414b6 | 754 | \r |
755 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
756 | bitwise AND between the read result and the value specified by AndData,\r | |
62991af2 | 757 | performs a bitwise OR between the result of the AND operation and\r |
e1f414b6 | 758 | the value specified by OrData, and writes the result to the 16-bit PCI\r |
759 | configuration register specified by Address. The value written to the PCI\r | |
760 | configuration register is returned. This function must guarantee that all PCI\r | |
761 | read and write operations are serialized.\r | |
762 | \r | |
763 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
764 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
765 | If the register specified by Address >= 0x100, then ASSERT().\r | |
766 | \r | |
2fc59a00 | 767 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 768 | Register.\r |
769 | @param AndData The value to AND with the PCI configuration register.\r | |
770 | @param OrData The value to OR with the result of the AND operation.\r | |
771 | \r | |
772 | @return The value written back to the PCI configuration register.\r | |
773 | \r | |
774 | **/\r | |
775 | UINT16\r | |
776 | EFIAPI\r | |
777 | PciCf8AndThenOr16 (\r | |
778 | IN UINTN Address,\r | |
779 | IN UINT16 AndData,\r | |
780 | IN UINT16 OrData\r | |
781 | )\r | |
782 | {\r | |
96dd57ee | 783 | BOOLEAN InterruptState;\r |
784 | UINT32 AddressPort;\r | |
785 | UINT16 Result;\r | |
9095d37b | 786 | \r |
e1f414b6 | 787 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 788 | InterruptState = SaveAndDisableInterrupts ();\r |
789 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 790 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 791 | Result = IoAndThenOr16 (\r |
792 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
793 | AndData,\r | |
794 | OrData\r | |
795 | );\r | |
796 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
797 | SetInterruptState (InterruptState);\r | |
798 | return Result;\r | |
e1f414b6 | 799 | }\r |
800 | \r | |
801 | /**\r | |
802 | Reads a bit field of a PCI configuration register.\r | |
803 | \r | |
804 | Reads the bit field in a 16-bit PCI configuration register. The bit field is\r | |
805 | specified by the StartBit and the EndBit. The value of the bit field is\r | |
806 | returned.\r | |
807 | \r | |
808 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
809 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
810 | If the register specified by Address >= 0x100, then ASSERT().\r | |
811 | If StartBit is greater than 15, then ASSERT().\r | |
812 | If EndBit is greater than 15, then ASSERT().\r | |
813 | If EndBit is less than StartBit, then ASSERT().\r | |
814 | \r | |
2fc59a00 | 815 | @param Address The PCI configuration register to read.\r |
e1f414b6 | 816 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
817 | Range 0..15.\r | |
818 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
819 | Range 0..15.\r | |
820 | \r | |
821 | @return The value of the bit field read from the PCI configuration register.\r | |
822 | \r | |
823 | **/\r | |
824 | UINT16\r | |
825 | EFIAPI\r | |
826 | PciCf8BitFieldRead16 (\r | |
827 | IN UINTN Address,\r | |
828 | IN UINTN StartBit,\r | |
829 | IN UINTN EndBit\r | |
830 | )\r | |
831 | {\r | |
96dd57ee | 832 | BOOLEAN InterruptState;\r |
833 | UINT32 AddressPort;\r | |
834 | UINT16 Result;\r | |
9095d37b | 835 | \r |
e1f414b6 | 836 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 837 | InterruptState = SaveAndDisableInterrupts ();\r |
838 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 839 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 840 | Result = IoBitFieldRead16 (\r |
841 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
842 | StartBit,\r | |
843 | EndBit\r | |
844 | );\r | |
845 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
846 | SetInterruptState (InterruptState);\r | |
847 | return Result;\r | |
e1f414b6 | 848 | }\r |
849 | \r | |
850 | /**\r | |
851 | Writes a bit field to a PCI configuration register.\r | |
852 | \r | |
853 | Writes Value to the bit field of the PCI configuration register. The bit\r | |
854 | field is specified by the StartBit and the EndBit. All other bits in the\r | |
855 | destination PCI configuration register are preserved. The new value of the\r | |
856 | 16-bit register is returned.\r | |
857 | \r | |
858 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
859 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
860 | If the register specified by Address >= 0x100, then ASSERT().\r | |
861 | If StartBit is greater than 15, then ASSERT().\r | |
862 | If EndBit is greater than 15, then ASSERT().\r | |
863 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 864 | If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 865 | \r |
2fc59a00 | 866 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 867 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
868 | Range 0..15.\r | |
869 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
870 | Range 0..15.\r | |
2fc59a00 | 871 | @param Value The new value of the bit field.\r |
e1f414b6 | 872 | \r |
873 | @return The value written back to the PCI configuration register.\r | |
874 | \r | |
875 | **/\r | |
876 | UINT16\r | |
877 | EFIAPI\r | |
878 | PciCf8BitFieldWrite16 (\r | |
879 | IN UINTN Address,\r | |
880 | IN UINTN StartBit,\r | |
881 | IN UINTN EndBit,\r | |
882 | IN UINT16 Value\r | |
883 | )\r | |
884 | {\r | |
96dd57ee | 885 | BOOLEAN InterruptState;\r |
886 | UINT32 AddressPort;\r | |
887 | UINT16 Result;\r | |
9095d37b | 888 | \r |
e1f414b6 | 889 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 890 | InterruptState = SaveAndDisableInterrupts ();\r |
891 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 892 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 893 | Result = IoBitFieldWrite16 (\r |
894 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
895 | StartBit,\r | |
896 | EndBit,\r | |
897 | Value\r | |
898 | );\r | |
899 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
900 | SetInterruptState (InterruptState);\r | |
901 | return Result;\r | |
e1f414b6 | 902 | }\r |
903 | \r | |
904 | /**\r | |
905 | Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r | |
906 | writes the result back to the bit field in the 16-bit port.\r | |
907 | \r | |
908 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 909 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 910 | OrData, and writes the result to the 16-bit PCI configuration register\r |
911 | specified by Address. The value written to the PCI configuration register is\r | |
912 | returned. This function must guarantee that all PCI read and write operations\r | |
913 | are serialized. Extra left bits in OrData are stripped.\r | |
914 | \r | |
915 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
916 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
917 | If the register specified by Address >= 0x100, then ASSERT().\r | |
918 | If StartBit is greater than 15, then ASSERT().\r | |
919 | If EndBit is greater than 15, then ASSERT().\r | |
920 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 921 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 922 | \r |
2fc59a00 | 923 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 924 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
925 | Range 0..15.\r | |
926 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
927 | Range 0..15.\r | |
928 | @param OrData The value to OR with the PCI configuration register.\r | |
929 | \r | |
930 | @return The value written back to the PCI configuration register.\r | |
931 | \r | |
932 | **/\r | |
933 | UINT16\r | |
934 | EFIAPI\r | |
935 | PciCf8BitFieldOr16 (\r | |
936 | IN UINTN Address,\r | |
937 | IN UINTN StartBit,\r | |
938 | IN UINTN EndBit,\r | |
939 | IN UINT16 OrData\r | |
940 | )\r | |
941 | {\r | |
96dd57ee | 942 | BOOLEAN InterruptState;\r |
943 | UINT32 AddressPort;\r | |
944 | UINT16 Result;\r | |
9095d37b | 945 | \r |
e1f414b6 | 946 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 947 | InterruptState = SaveAndDisableInterrupts ();\r |
948 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 949 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 950 | Result = IoBitFieldOr16 (\r |
951 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
952 | StartBit,\r | |
953 | EndBit,\r | |
954 | OrData\r | |
955 | );\r | |
956 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
957 | SetInterruptState (InterruptState);\r | |
958 | return Result;\r | |
e1f414b6 | 959 | }\r |
960 | \r | |
961 | /**\r | |
962 | Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r | |
963 | AND, and writes the result back to the bit field in the 16-bit register.\r | |
964 | \r | |
965 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
966 | bitwise AND between the read result and the value specified by AndData, and\r | |
967 | writes the result to the 16-bit PCI configuration register specified by\r | |
968 | Address. The value written to the PCI configuration register is returned.\r | |
969 | This function must guarantee that all PCI read and write operations are\r | |
970 | serialized. Extra left bits in AndData are stripped.\r | |
971 | \r | |
972 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
973 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
974 | If the register specified by Address >= 0x100, then ASSERT().\r | |
975 | If StartBit is greater than 15, then ASSERT().\r | |
976 | If EndBit is greater than 15, then ASSERT().\r | |
977 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 978 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 979 | \r |
2fc59a00 | 980 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 981 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
982 | Range 0..15.\r | |
983 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
984 | Range 0..15.\r | |
985 | @param AndData The value to AND with the PCI configuration register.\r | |
986 | \r | |
987 | @return The value written back to the PCI configuration register.\r | |
988 | \r | |
989 | **/\r | |
990 | UINT16\r | |
991 | EFIAPI\r | |
992 | PciCf8BitFieldAnd16 (\r | |
993 | IN UINTN Address,\r | |
994 | IN UINTN StartBit,\r | |
995 | IN UINTN EndBit,\r | |
996 | IN UINT16 AndData\r | |
997 | )\r | |
998 | {\r | |
96dd57ee | 999 | BOOLEAN InterruptState;\r |
1000 | UINT32 AddressPort;\r | |
1001 | UINT16 Result;\r | |
9095d37b | 1002 | \r |
e1f414b6 | 1003 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 1004 | InterruptState = SaveAndDisableInterrupts ();\r |
1005 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1006 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1007 | Result = IoBitFieldAnd16 (\r |
1008 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
1009 | StartBit,\r | |
1010 | EndBit,\r | |
1011 | AndData\r | |
1012 | );\r | |
1013 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1014 | SetInterruptState (InterruptState);\r | |
1015 | return Result;\r | |
e1f414b6 | 1016 | }\r |
1017 | \r | |
1018 | /**\r | |
1019 | Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r | |
62991af2 | 1020 | bitwise OR, and writes the result back to the bit field in the\r |
e1f414b6 | 1021 | 16-bit port.\r |
1022 | \r | |
1023 | Reads the 16-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 1024 | bitwise AND followed by a bitwise OR between the read result and\r |
e1f414b6 | 1025 | the value specified by AndData, and writes the result to the 16-bit PCI\r |
1026 | configuration register specified by Address. The value written to the PCI\r | |
1027 | configuration register is returned. This function must guarantee that all PCI\r | |
1028 | read and write operations are serialized. Extra left bits in both AndData and\r | |
1029 | OrData are stripped.\r | |
1030 | \r | |
1031 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1032 | If Address is not aligned on a 16-bit boundary, then ASSERT().\r | |
1033 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1034 | If StartBit is greater than 15, then ASSERT().\r | |
1035 | If EndBit is greater than 15, then ASSERT().\r | |
1036 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 LG |
1037 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
1038 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r | |
e1f414b6 | 1039 | \r |
2fc59a00 | 1040 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 1041 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1042 | Range 0..15.\r | |
1043 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1044 | Range 0..15.\r | |
1045 | @param AndData The value to AND with the PCI configuration register.\r | |
1046 | @param OrData The value to OR with the result of the AND operation.\r | |
1047 | \r | |
1048 | @return The value written back to the PCI configuration register.\r | |
1049 | \r | |
1050 | **/\r | |
1051 | UINT16\r | |
1052 | EFIAPI\r | |
1053 | PciCf8BitFieldAndThenOr16(\r | |
1054 | IN UINTN Address,\r | |
1055 | IN UINTN StartBit,\r | |
1056 | IN UINTN EndBit,\r | |
1057 | IN UINT16 AndData,\r | |
1058 | IN UINT16 OrData\r | |
1059 | )\r | |
1060 | {\r | |
96dd57ee | 1061 | BOOLEAN InterruptState;\r |
1062 | UINT32 AddressPort;\r | |
1063 | UINT16 Result;\r | |
9095d37b | 1064 | \r |
e1f414b6 | 1065 | ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r |
96dd57ee | 1066 | InterruptState = SaveAndDisableInterrupts ();\r |
1067 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1068 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1069 | Result = IoBitFieldAndThenOr16 (\r |
1070 | PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r | |
1071 | StartBit,\r | |
1072 | EndBit,\r | |
1073 | AndData,\r | |
1074 | OrData\r | |
1075 | );\r | |
1076 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1077 | SetInterruptState (InterruptState);\r | |
1078 | return Result;\r | |
e1f414b6 | 1079 | }\r |
1080 | \r | |
1081 | /**\r | |
1082 | Reads a 32-bit PCI configuration register.\r | |
1083 | \r | |
1084 | Reads and returns the 32-bit PCI configuration register specified by Address.\r | |
1085 | This function must guarantee that all PCI read and write operations are\r | |
1086 | serialized.\r | |
1087 | \r | |
1088 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1089 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1090 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1091 | \r | |
2fc59a00 | 1092 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 1093 | Register.\r |
1094 | \r | |
1095 | @return The read value from the PCI configuration register.\r | |
1096 | \r | |
1097 | **/\r | |
1098 | UINT32\r | |
1099 | EFIAPI\r | |
1100 | PciCf8Read32 (\r | |
1101 | IN UINTN Address\r | |
1102 | )\r | |
1103 | {\r | |
96dd57ee | 1104 | BOOLEAN InterruptState;\r |
1105 | UINT32 AddressPort;\r | |
1106 | UINT32 Result;\r | |
9095d37b | 1107 | \r |
e1f414b6 | 1108 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1109 | InterruptState = SaveAndDisableInterrupts ();\r |
1110 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1111 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1112 | Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);\r |
1113 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1114 | SetInterruptState (InterruptState);\r | |
1115 | return Result;\r | |
e1f414b6 | 1116 | }\r |
1117 | \r | |
1118 | /**\r | |
1119 | Writes a 32-bit PCI configuration register.\r | |
1120 | \r | |
1121 | Writes the 32-bit PCI configuration register specified by Address with the\r | |
1122 | value specified by Value. Value is returned. This function must guarantee\r | |
1123 | that all PCI read and write operations are serialized.\r | |
1124 | \r | |
1125 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1126 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1127 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1128 | \r | |
2fc59a00 | 1129 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 1130 | Register.\r |
1131 | @param Value The value to write.\r | |
1132 | \r | |
1133 | @return The value written to the PCI configuration register.\r | |
1134 | \r | |
1135 | **/\r | |
1136 | UINT32\r | |
1137 | EFIAPI\r | |
1138 | PciCf8Write32 (\r | |
1139 | IN UINTN Address,\r | |
1140 | IN UINT32 Value\r | |
1141 | )\r | |
1142 | {\r | |
96dd57ee | 1143 | BOOLEAN InterruptState;\r |
1144 | UINT32 AddressPort;\r | |
1145 | UINT32 Result;\r | |
9095d37b | 1146 | \r |
e1f414b6 | 1147 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1148 | InterruptState = SaveAndDisableInterrupts ();\r |
1149 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1150 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1151 | Result = IoWrite32 (\r |
1152 | PCI_CONFIGURATION_DATA_PORT,\r | |
1153 | Value\r | |
1154 | );\r | |
1155 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1156 | SetInterruptState (InterruptState);\r | |
1157 | return Result;\r | |
e1f414b6 | 1158 | }\r |
1159 | \r | |
1160 | /**\r | |
62991af2 | 1161 | Performs a bitwise OR of a 32-bit PCI configuration register with\r |
e1f414b6 | 1162 | a 32-bit value.\r |
1163 | \r | |
1164 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 1165 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 1166 | OrData, and writes the result to the 32-bit PCI configuration register\r |
1167 | specified by Address. The value written to the PCI configuration register is\r | |
1168 | returned. This function must guarantee that all PCI read and write operations\r | |
1169 | are serialized.\r | |
1170 | \r | |
1171 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1172 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1173 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1174 | \r | |
2fc59a00 | 1175 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 1176 | Register.\r |
1177 | @param OrData The value to OR with the PCI configuration register.\r | |
1178 | \r | |
1179 | @return The value written back to the PCI configuration register.\r | |
1180 | \r | |
1181 | **/\r | |
1182 | UINT32\r | |
1183 | EFIAPI\r | |
1184 | PciCf8Or32 (\r | |
1185 | IN UINTN Address,\r | |
1186 | IN UINT32 OrData\r | |
1187 | )\r | |
1188 | {\r | |
96dd57ee | 1189 | BOOLEAN InterruptState;\r |
1190 | UINT32 AddressPort;\r | |
1191 | UINT32 Result;\r | |
9095d37b | 1192 | \r |
e1f414b6 | 1193 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1194 | InterruptState = SaveAndDisableInterrupts ();\r |
1195 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1196 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1197 | Result = IoOr32 (\r |
1198 | PCI_CONFIGURATION_DATA_PORT,\r | |
1199 | OrData\r | |
1200 | );\r | |
1201 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1202 | SetInterruptState (InterruptState);\r | |
1203 | return Result;\r | |
e1f414b6 | 1204 | }\r |
1205 | \r | |
1206 | /**\r | |
1207 | Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r | |
1208 | value.\r | |
1209 | \r | |
1210 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
1211 | bitwise AND between the read result and the value specified by AndData, and\r | |
1212 | writes the result to the 32-bit PCI configuration register specified by\r | |
1213 | Address. The value written to the PCI configuration register is returned.\r | |
1214 | This function must guarantee that all PCI read and write operations are\r | |
1215 | serialized.\r | |
1216 | \r | |
1217 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1218 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1219 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1220 | \r | |
2fc59a00 | 1221 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 1222 | Register.\r |
1223 | @param AndData The value to AND with the PCI configuration register.\r | |
1224 | \r | |
1225 | @return The value written back to the PCI configuration register.\r | |
1226 | \r | |
1227 | **/\r | |
1228 | UINT32\r | |
1229 | EFIAPI\r | |
1230 | PciCf8And32 (\r | |
1231 | IN UINTN Address,\r | |
1232 | IN UINT32 AndData\r | |
1233 | )\r | |
1234 | {\r | |
96dd57ee | 1235 | BOOLEAN InterruptState;\r |
1236 | UINT32 AddressPort;\r | |
1237 | UINT32 Result;\r | |
9095d37b | 1238 | \r |
e1f414b6 | 1239 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1240 | InterruptState = SaveAndDisableInterrupts ();\r |
1241 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1242 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1243 | Result = IoAnd32 (\r |
1244 | PCI_CONFIGURATION_DATA_PORT,\r | |
1245 | AndData\r | |
1246 | );\r | |
1247 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1248 | SetInterruptState (InterruptState);\r | |
1249 | return Result;\r | |
e1f414b6 | 1250 | }\r |
1251 | \r | |
1252 | /**\r | |
1253 | Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r | |
62991af2 | 1254 | value, followed a bitwise OR with another 32-bit value.\r |
e1f414b6 | 1255 | \r |
1256 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
1257 | bitwise AND between the read result and the value specified by AndData,\r | |
62991af2 | 1258 | performs a bitwise OR between the result of the AND operation and\r |
e1f414b6 | 1259 | the value specified by OrData, and writes the result to the 32-bit PCI\r |
1260 | configuration register specified by Address. The value written to the PCI\r | |
1261 | configuration register is returned. This function must guarantee that all PCI\r | |
1262 | read and write operations are serialized.\r | |
1263 | \r | |
1264 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1265 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1266 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1267 | \r | |
2fc59a00 | 1268 | @param Address The address that encodes the PCI Bus, Device, Function and\r |
e1f414b6 | 1269 | Register.\r |
1270 | @param AndData The value to AND with the PCI configuration register.\r | |
1271 | @param OrData The value to OR with the result of the AND operation.\r | |
1272 | \r | |
1273 | @return The value written back to the PCI configuration register.\r | |
1274 | \r | |
1275 | **/\r | |
1276 | UINT32\r | |
1277 | EFIAPI\r | |
1278 | PciCf8AndThenOr32 (\r | |
1279 | IN UINTN Address,\r | |
1280 | IN UINT32 AndData,\r | |
1281 | IN UINT32 OrData\r | |
1282 | )\r | |
1283 | {\r | |
96dd57ee | 1284 | BOOLEAN InterruptState;\r |
1285 | UINT32 AddressPort;\r | |
1286 | UINT32 Result;\r | |
9095d37b | 1287 | \r |
e1f414b6 | 1288 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1289 | InterruptState = SaveAndDisableInterrupts ();\r |
1290 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1291 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1292 | Result = IoAndThenOr32 (\r |
1293 | PCI_CONFIGURATION_DATA_PORT,\r | |
1294 | AndData,\r | |
1295 | OrData\r | |
1296 | );\r | |
1297 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1298 | SetInterruptState (InterruptState);\r | |
1299 | return Result;\r | |
e1f414b6 | 1300 | }\r |
1301 | \r | |
1302 | /**\r | |
1303 | Reads a bit field of a PCI configuration register.\r | |
1304 | \r | |
1305 | Reads the bit field in a 32-bit PCI configuration register. The bit field is\r | |
1306 | specified by the StartBit and the EndBit. The value of the bit field is\r | |
1307 | returned.\r | |
1308 | \r | |
1309 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1310 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1311 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1312 | If StartBit is greater than 31, then ASSERT().\r | |
1313 | If EndBit is greater than 31, then ASSERT().\r | |
1314 | If EndBit is less than StartBit, then ASSERT().\r | |
1315 | \r | |
2fc59a00 | 1316 | @param Address The PCI configuration register to read.\r |
e1f414b6 | 1317 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1318 | Range 0..31.\r | |
1319 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1320 | Range 0..31.\r | |
1321 | \r | |
1322 | @return The value of the bit field read from the PCI configuration register.\r | |
1323 | \r | |
1324 | **/\r | |
1325 | UINT32\r | |
1326 | EFIAPI\r | |
1327 | PciCf8BitFieldRead32 (\r | |
1328 | IN UINTN Address,\r | |
1329 | IN UINTN StartBit,\r | |
1330 | IN UINTN EndBit\r | |
1331 | )\r | |
1332 | {\r | |
96dd57ee | 1333 | BOOLEAN InterruptState;\r |
1334 | UINT32 AddressPort;\r | |
1335 | UINT32 Result;\r | |
9095d37b | 1336 | \r |
e1f414b6 | 1337 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1338 | InterruptState = SaveAndDisableInterrupts ();\r |
1339 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1340 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1341 | Result = IoBitFieldRead32 (\r |
1342 | PCI_CONFIGURATION_DATA_PORT,\r | |
1343 | StartBit,\r | |
1344 | EndBit\r | |
1345 | );\r | |
1346 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1347 | SetInterruptState (InterruptState);\r | |
1348 | return Result;\r | |
e1f414b6 | 1349 | }\r |
1350 | \r | |
1351 | /**\r | |
1352 | Writes a bit field to a PCI configuration register.\r | |
1353 | \r | |
1354 | Writes Value to the bit field of the PCI configuration register. The bit\r | |
1355 | field is specified by the StartBit and the EndBit. All other bits in the\r | |
1356 | destination PCI configuration register are preserved. The new value of the\r | |
1357 | 32-bit register is returned.\r | |
1358 | \r | |
1359 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1360 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1361 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1362 | If StartBit is greater than 31, then ASSERT().\r | |
1363 | If EndBit is greater than 31, then ASSERT().\r | |
1364 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 1365 | If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 1366 | \r |
2fc59a00 | 1367 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 1368 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1369 | Range 0..31.\r | |
1370 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1371 | Range 0..31.\r | |
2fc59a00 | 1372 | @param Value The new value of the bit field.\r |
e1f414b6 | 1373 | \r |
1374 | @return The value written back to the PCI configuration register.\r | |
1375 | \r | |
1376 | **/\r | |
1377 | UINT32\r | |
1378 | EFIAPI\r | |
1379 | PciCf8BitFieldWrite32 (\r | |
1380 | IN UINTN Address,\r | |
1381 | IN UINTN StartBit,\r | |
1382 | IN UINTN EndBit,\r | |
1383 | IN UINT32 Value\r | |
1384 | )\r | |
1385 | {\r | |
96dd57ee | 1386 | BOOLEAN InterruptState;\r |
1387 | UINT32 AddressPort;\r | |
1388 | UINT32 Result;\r | |
9095d37b | 1389 | \r |
e1f414b6 | 1390 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1391 | InterruptState = SaveAndDisableInterrupts ();\r |
1392 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1393 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1394 | Result = IoBitFieldWrite32 (\r |
1395 | PCI_CONFIGURATION_DATA_PORT,\r | |
1396 | StartBit,\r | |
1397 | EndBit,\r | |
1398 | Value\r | |
1399 | );\r | |
1400 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1401 | SetInterruptState (InterruptState);\r | |
1402 | return Result;\r | |
e1f414b6 | 1403 | }\r |
1404 | \r | |
1405 | /**\r | |
1406 | Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r | |
1407 | writes the result back to the bit field in the 32-bit port.\r | |
1408 | \r | |
1409 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 1410 | bitwise OR between the read result and the value specified by\r |
e1f414b6 | 1411 | OrData, and writes the result to the 32-bit PCI configuration register\r |
1412 | specified by Address. The value written to the PCI configuration register is\r | |
1413 | returned. This function must guarantee that all PCI read and write operations\r | |
1414 | are serialized. Extra left bits in OrData are stripped.\r | |
1415 | \r | |
1416 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1417 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1418 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1419 | If StartBit is greater than 31, then ASSERT().\r | |
1420 | If EndBit is greater than 31, then ASSERT().\r | |
1421 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 1422 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 1423 | \r |
2fc59a00 | 1424 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 1425 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1426 | Range 0..31.\r | |
1427 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1428 | Range 0..31.\r | |
1429 | @param OrData The value to OR with the PCI configuration register.\r | |
1430 | \r | |
1431 | @return The value written back to the PCI configuration register.\r | |
1432 | \r | |
1433 | **/\r | |
1434 | UINT32\r | |
1435 | EFIAPI\r | |
1436 | PciCf8BitFieldOr32 (\r | |
1437 | IN UINTN Address,\r | |
1438 | IN UINTN StartBit,\r | |
1439 | IN UINTN EndBit,\r | |
1440 | IN UINT32 OrData\r | |
1441 | )\r | |
1442 | {\r | |
96dd57ee | 1443 | BOOLEAN InterruptState;\r |
1444 | UINT32 AddressPort;\r | |
1445 | UINT32 Result;\r | |
9095d37b | 1446 | \r |
e1f414b6 | 1447 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1448 | InterruptState = SaveAndDisableInterrupts ();\r |
1449 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1450 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1451 | Result = IoBitFieldOr32 (\r |
1452 | PCI_CONFIGURATION_DATA_PORT,\r | |
1453 | StartBit,\r | |
1454 | EndBit,\r | |
1455 | OrData\r | |
1456 | );\r | |
1457 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1458 | SetInterruptState (InterruptState);\r | |
1459 | return Result;\r | |
e1f414b6 | 1460 | }\r |
1461 | \r | |
1462 | /**\r | |
1463 | Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r | |
1464 | AND, and writes the result back to the bit field in the 32-bit register.\r | |
1465 | \r | |
1466 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
1467 | bitwise AND between the read result and the value specified by AndData, and\r | |
1468 | writes the result to the 32-bit PCI configuration register specified by\r | |
1469 | Address. The value written to the PCI configuration register is returned.\r | |
1470 | This function must guarantee that all PCI read and write operations are\r | |
1471 | serialized. Extra left bits in AndData are stripped.\r | |
1472 | \r | |
1473 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1474 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1475 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1476 | If StartBit is greater than 31, then ASSERT().\r | |
1477 | If EndBit is greater than 31, then ASSERT().\r | |
1478 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 | 1479 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
e1f414b6 | 1480 | \r |
2fc59a00 | 1481 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 1482 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1483 | Range 0..31.\r | |
1484 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1485 | Range 0..31.\r | |
1486 | @param AndData The value to AND with the PCI configuration register.\r | |
1487 | \r | |
1488 | @return The value written back to the PCI configuration register.\r | |
1489 | \r | |
1490 | **/\r | |
1491 | UINT32\r | |
1492 | EFIAPI\r | |
1493 | PciCf8BitFieldAnd32 (\r | |
1494 | IN UINTN Address,\r | |
1495 | IN UINTN StartBit,\r | |
1496 | IN UINTN EndBit,\r | |
1497 | IN UINT32 AndData\r | |
1498 | )\r | |
1499 | {\r | |
96dd57ee | 1500 | BOOLEAN InterruptState;\r |
1501 | UINT32 AddressPort;\r | |
1502 | UINT32 Result;\r | |
9095d37b | 1503 | \r |
e1f414b6 | 1504 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1505 | InterruptState = SaveAndDisableInterrupts ();\r |
1506 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1507 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1508 | Result = IoBitFieldAnd32 (\r |
1509 | PCI_CONFIGURATION_DATA_PORT,\r | |
1510 | StartBit,\r | |
1511 | EndBit,\r | |
1512 | AndData\r | |
1513 | );\r | |
1514 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1515 | SetInterruptState (InterruptState);\r | |
1516 | return Result;\r | |
e1f414b6 | 1517 | }\r |
1518 | \r | |
1519 | /**\r | |
1520 | Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r | |
62991af2 | 1521 | bitwise OR, and writes the result back to the bit field in the\r |
e1f414b6 | 1522 | 32-bit port.\r |
1523 | \r | |
1524 | Reads the 32-bit PCI configuration register specified by Address, performs a\r | |
62991af2 | 1525 | bitwise AND followed by a bitwise OR between the read result and\r |
e1f414b6 | 1526 | the value specified by AndData, and writes the result to the 32-bit PCI\r |
1527 | configuration register specified by Address. The value written to the PCI\r | |
1528 | configuration register is returned. This function must guarantee that all PCI\r | |
1529 | read and write operations are serialized. Extra left bits in both AndData and\r | |
1530 | OrData are stripped.\r | |
1531 | \r | |
1532 | If Address > 0x0FFFFFFF, then ASSERT().\r | |
1533 | If Address is not aligned on a 32-bit boundary, then ASSERT().\r | |
1534 | If the register specified by Address >= 0x100, then ASSERT().\r | |
1535 | If StartBit is greater than 31, then ASSERT().\r | |
1536 | If EndBit is greater than 31, then ASSERT().\r | |
1537 | If EndBit is less than StartBit, then ASSERT().\r | |
94952554 LG |
1538 | If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r |
1539 | If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r | |
e1f414b6 | 1540 | \r |
2fc59a00 | 1541 | @param Address The PCI configuration register to write.\r |
e1f414b6 | 1542 | @param StartBit The ordinal of the least significant bit in the bit field.\r |
1543 | Range 0..31.\r | |
1544 | @param EndBit The ordinal of the most significant bit in the bit field.\r | |
1545 | Range 0..31.\r | |
1546 | @param AndData The value to AND with the PCI configuration register.\r | |
1547 | @param OrData The value to OR with the result of the AND operation.\r | |
1548 | \r | |
1549 | @return The value written back to the PCI configuration register.\r | |
1550 | \r | |
1551 | **/\r | |
1552 | UINT32\r | |
1553 | EFIAPI\r | |
1554 | PciCf8BitFieldAndThenOr32(\r | |
1555 | IN UINTN Address,\r | |
1556 | IN UINTN StartBit,\r | |
1557 | IN UINTN EndBit,\r | |
1558 | IN UINT32 AndData,\r | |
1559 | IN UINT32 OrData\r | |
1560 | )\r | |
1561 | {\r | |
96dd57ee | 1562 | BOOLEAN InterruptState;\r |
1563 | UINT32 AddressPort;\r | |
1564 | UINT32 Result;\r | |
9095d37b | 1565 | \r |
e1f414b6 | 1566 | ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r |
96dd57ee | 1567 | InterruptState = SaveAndDisableInterrupts ();\r |
1568 | AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r | |
e1f414b6 | 1569 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r |
96dd57ee | 1570 | Result = IoBitFieldAndThenOr32 (\r |
1571 | PCI_CONFIGURATION_DATA_PORT,\r | |
1572 | StartBit,\r | |
1573 | EndBit,\r | |
1574 | AndData,\r | |
1575 | OrData\r | |
1576 | );\r | |
1577 | IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r | |
1578 | SetInterruptState (InterruptState);\r | |
1579 | return Result;\r | |
e1f414b6 | 1580 | }\r |
1581 | \r | |
1582 | /**\r | |
1583 | Reads a range of PCI configuration registers into a caller supplied buffer.\r | |
1584 | \r | |
1585 | Reads the range of PCI configuration registers specified by StartAddress and\r | |
1586 | Size into the buffer specified by Buffer. This function only allows the PCI\r | |
1587 | configuration registers from a single PCI function to be read. Size is\r | |
1588 | returned. When possible 32-bit PCI configuration read cycles are used to read\r | |
1589 | from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r | |
1590 | and 16-bit PCI configuration read cycles may be used at the beginning and the\r | |
1591 | end of the range.\r | |
1592 | \r | |
1593 | If StartAddress > 0x0FFFFFFF, then ASSERT().\r | |
1594 | If the register specified by StartAddress >= 0x100, then ASSERT().\r | |
1595 | If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r | |
1596 | If Size > 0 and Buffer is NULL, then ASSERT().\r | |
1597 | \r | |
2fc59a00 | 1598 | @param StartAddress The starting address that encodes the PCI Bus, Device,\r |
e1f414b6 | 1599 | Function and Register.\r |
2fc59a00 | 1600 | @param Size The size in bytes of the transfer.\r |
1601 | @param Buffer The pointer to a buffer receiving the data read.\r | |
e1f414b6 | 1602 | \r |
9638ba6d | 1603 | @return Size read from StartAddress.\r |
e1f414b6 | 1604 | \r |
1605 | **/\r | |
1606 | UINTN\r | |
1607 | EFIAPI\r | |
1608 | PciCf8ReadBuffer (\r | |
1609 | IN UINTN StartAddress,\r | |
1610 | IN UINTN Size,\r | |
1611 | OUT VOID *Buffer\r | |
1612 | )\r | |
1613 | {\r | |
0c62737d | 1614 | UINTN ReturnValue;\r |
e1f414b6 | 1615 | \r |
1616 | ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r | |
1617 | ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r | |
1618 | \r | |
1619 | if (Size == 0) {\r | |
1620 | return Size;\r | |
1621 | }\r | |
1622 | \r | |
1623 | ASSERT (Buffer != NULL);\r | |
1624 | \r | |
1625 | //\r | |
1626 | // Save Size for return\r | |
1627 | //\r | |
1628 | ReturnValue = Size;\r | |
1629 | \r | |
1630 | if ((StartAddress & 1) != 0) {\r | |
1631 | //\r | |
1632 | // Read a byte if StartAddress is byte aligned\r | |
1633 | //\r | |
1634 | *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r | |
1635 | StartAddress += sizeof (UINT8);\r | |
1636 | Size -= sizeof (UINT8);\r | |
1637 | Buffer = (UINT8*)Buffer + 1;\r | |
1638 | }\r | |
1639 | \r | |
1640 | if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r | |
1641 | //\r | |
1642 | // Read a word if StartAddress is word aligned\r | |
1643 | //\r | |
af2bb549 | 1644 | WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r |
0c62737d | 1645 | \r |
e1f414b6 | 1646 | StartAddress += sizeof (UINT16);\r |
1647 | Size -= sizeof (UINT16);\r | |
1648 | Buffer = (UINT16*)Buffer + 1;\r | |
1649 | }\r | |
1650 | \r | |
1651 | while (Size >= sizeof (UINT32)) {\r | |
1652 | //\r | |
1653 | // Read as many double words as possible\r | |
1654 | //\r | |
af2bb549 | 1655 | WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));\r |
e1f414b6 | 1656 | StartAddress += sizeof (UINT32);\r |
1657 | Size -= sizeof (UINT32);\r | |
1658 | Buffer = (UINT32*)Buffer + 1;\r | |
1659 | }\r | |
1660 | \r | |
1661 | if (Size >= sizeof (UINT16)) {\r | |
1662 | //\r | |
1663 | // Read the last remaining word if exist\r | |
1664 | //\r | |
af2bb549 | 1665 | WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r |
e1f414b6 | 1666 | StartAddress += sizeof (UINT16);\r |
1667 | Size -= sizeof (UINT16);\r | |
1668 | Buffer = (UINT16*)Buffer + 1;\r | |
1669 | }\r | |
1670 | \r | |
1671 | if (Size >= sizeof (UINT8)) {\r | |
1672 | //\r | |
1673 | // Read the last remaining byte if exist\r | |
1674 | //\r | |
1675 | *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r | |
1676 | }\r | |
1677 | \r | |
1678 | return ReturnValue;\r | |
1679 | }\r | |
1680 | \r | |
1681 | /**\r | |
1682 | Copies the data in a caller supplied buffer to a specified range of PCI\r | |
1683 | configuration space.\r | |
1684 | \r | |
1685 | Writes the range of PCI configuration registers specified by StartAddress and\r | |
1686 | Size from the buffer specified by Buffer. This function only allows the PCI\r | |
1687 | configuration registers from a single PCI function to be written. Size is\r | |
1688 | returned. When possible 32-bit PCI configuration write cycles are used to\r | |
1689 | write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r | |
1690 | 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r | |
1691 | and the end of the range.\r | |
1692 | \r | |
1693 | If StartAddress > 0x0FFFFFFF, then ASSERT().\r | |
1694 | If the register specified by StartAddress >= 0x100, then ASSERT().\r | |
1695 | If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r | |
1696 | If Size > 0 and Buffer is NULL, then ASSERT().\r | |
1697 | \r | |
2fc59a00 | 1698 | @param StartAddress The starting address that encodes the PCI Bus, Device,\r |
e1f414b6 | 1699 | Function and Register.\r |
2fc59a00 | 1700 | @param Size The size in bytes of the transfer.\r |
1701 | @param Buffer The pointer to a buffer containing the data to write.\r | |
e1f414b6 | 1702 | \r |
9638ba6d | 1703 | @return Size written to StartAddress.\r |
e1f414b6 | 1704 | \r |
1705 | **/\r | |
1706 | UINTN\r | |
1707 | EFIAPI\r | |
1708 | PciCf8WriteBuffer (\r | |
1709 | IN UINTN StartAddress,\r | |
1710 | IN UINTN Size,\r | |
1711 | IN VOID *Buffer\r | |
1712 | )\r | |
1713 | {\r | |
0c62737d | 1714 | UINTN ReturnValue;\r |
e1f414b6 | 1715 | \r |
1716 | ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r | |
1717 | ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r | |
1718 | \r | |
1719 | if (Size == 0) {\r | |
1720 | return 0;\r | |
1721 | }\r | |
1722 | \r | |
1723 | ASSERT (Buffer != NULL);\r | |
1724 | \r | |
1725 | //\r | |
1726 | // Save Size for return\r | |
1727 | //\r | |
1728 | ReturnValue = Size;\r | |
1729 | \r | |
1730 | if ((StartAddress & 1) != 0) {\r | |
1731 | //\r | |
1732 | // Write a byte if StartAddress is byte aligned\r | |
1733 | //\r | |
1734 | PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r | |
1735 | StartAddress += sizeof (UINT8);\r | |
1736 | Size -= sizeof (UINT8);\r | |
1737 | Buffer = (UINT8*)Buffer + 1;\r | |
1738 | }\r | |
1739 | \r | |
1740 | if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r | |
1741 | //\r | |
1742 | // Write a word if StartAddress is word aligned\r | |
1743 | //\r | |
0c62737d | 1744 | PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r |
e1f414b6 | 1745 | StartAddress += sizeof (UINT16);\r |
1746 | Size -= sizeof (UINT16);\r | |
1747 | Buffer = (UINT16*)Buffer + 1;\r | |
1748 | }\r | |
1749 | \r | |
1750 | while (Size >= sizeof (UINT32)) {\r | |
1751 | //\r | |
1752 | // Write as many double words as possible\r | |
1753 | //\r | |
0c62737d | 1754 | PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));\r |
e1f414b6 | 1755 | StartAddress += sizeof (UINT32);\r |
1756 | Size -= sizeof (UINT32);\r | |
1757 | Buffer = (UINT32*)Buffer + 1;\r | |
1758 | }\r | |
1759 | \r | |
1760 | if (Size >= sizeof (UINT16)) {\r | |
1761 | //\r | |
1762 | // Write the last remaining word if exist\r | |
1763 | //\r | |
0c62737d | 1764 | PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r |
e1f414b6 | 1765 | StartAddress += sizeof (UINT16);\r |
1766 | Size -= sizeof (UINT16);\r | |
1767 | Buffer = (UINT16*)Buffer + 1;\r | |
1768 | }\r | |
1769 | \r | |
1770 | if (Size >= sizeof (UINT8)) {\r | |
1771 | //\r | |
1772 | // Write the last remaining byte if exist\r | |
1773 | //\r | |
1774 | PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r | |
1775 | }\r | |
1776 | \r | |
1777 | return ReturnValue;\r | |
1778 | }\r |