]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoLib.c
Add comments.
[mirror_edk2.git] / IntelFrameworkPkg / Library / DxeIoLibCpuIo / IoLib.c
1 /** @file
2 I/O Library.
3 The implementation of I/O operation for this library instance
4 are based on EFI_CPU_IO_PROTOCOL.
5
6 Copyright (c) 2006, Intel Corporation<BR>
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 Module Name: IoLib.c
16
17 **/
18
19
20 #include "DxeCpuIoLibInternal.h"
21
22 //
23 // Globle varible to cache pointer to CpuIo protocol.
24 //
25 STATIC EFI_CPU_IO_PROTOCOL *mCpuIo = NULL;
26 STATIC EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo = NULL;
27
28 /**
29 The constructor function caches the pointer to CpuIo protocol.
30
31 The constructor function locates CpuIo protocol from protocol database.
32 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
33
34 @param ImageHandle The firmware allocated handle for the EFI image.
35 @param SystemTable A pointer to the EFI System Table.
36
37 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
38
39 **/
40 EFI_STATUS
41 EFIAPI
42 IoLibConstructor (
43 IN EFI_HANDLE ImageHandle,
44 IN EFI_SYSTEM_TABLE *SystemTable
45 )
46 {
47 EFI_STATUS Status;
48
49 Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &mPciRootBridgeIo);
50 if (EFI_ERROR (Status)) {
51 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo);
52 }
53 ASSERT_EFI_ERROR (Status);
54
55 return Status;
56 }
57
58 /**
59 Reads registers in the EFI CPU I/O space.
60
61 Reads the I/O port specified by Port with registers width specified by Width.
62 The read value is returned. If such operations are not supported, then ASSERT().
63 This function must guarantee that all I/O read and write operations are serialized.
64
65 @param Port The base address of the I/O operation.
66 The caller is responsible for aligning the Address if required.
67 @param Width The width of the I/O operation.
68
69 @return Data read from registers in the EFI CPU I/O space.
70
71 **/
72 UINT64
73 EFIAPI
74 IoReadWorker (
75 IN UINTN Port,
76 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
77 )
78 {
79 EFI_STATUS Status;
80 UINT64 Data;
81
82 if (mPciRootBridgeIo != NULL) {
83 Status = mPciRootBridgeIo->Io.Read (mPciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, Port, 1, &Data);
84 } else {
85 Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);
86 }
87 ASSERT_EFI_ERROR (Status);
88
89 return Data;
90 }
91
92 /**
93 Writes registers in the EFI CPU I/O space.
94
95 Writes the I/O port specified by Port with registers width and value specified by Width
96 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().
97 This function must guarantee that all I/O read and write operations are serialized.
98
99 @param Port The base address of the I/O operation.
100 The caller is responsible for aligning the Address if required.
101 @param Width The width of the I/O operation.
102 @param Data The value to write to the I/O port.
103
104 @return The paramter of Data.
105
106 **/
107 UINT64
108 EFIAPI
109 IoWriteWorker (
110 IN UINTN Port,
111 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
112 IN UINT64 Data
113 )
114 {
115 EFI_STATUS Status;
116
117 if (mPciRootBridgeIo != NULL) {
118 Status = mPciRootBridgeIo->Io.Write (mPciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, Port, 1, &Data);
119 } else {
120 Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);
121 }
122 ASSERT_EFI_ERROR (Status);
123
124 return Data;
125 }
126
127 /**
128 Reads memory-mapped registers in the EFI system memory space.
129
130 Reads the MMIO registers specified by Address with registers width specified by Width.
131 The read value is returned. If such operations are not supported, then ASSERT().
132 This function must guarantee that all MMIO read and write operations are serialized.
133
134 @param Address The MMIO register to read.
135 The caller is responsible for aligning the Address if required.
136 @param Width The width of the I/O operation.
137
138 @return Data read from registers in the EFI system memory space.
139
140 **/
141 UINT64
142 EFIAPI
143 MmioReadWorker (
144 IN UINTN Address,
145 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
146 )
147 {
148 EFI_STATUS Status;
149 UINT64 Data;
150
151 if (mPciRootBridgeIo != NULL) {
152 Status = mPciRootBridgeIo->Mem.Read (mPciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, Address, 1, &Data);
153 } else {
154 Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);
155 }
156 ASSERT_EFI_ERROR (Status);
157
158 return Data;
159 }
160
161 /**
162 Writes memory-mapped registers in the EFI system memory space.
163
164 Writes the MMIO registers specified by Address with registers width and value specified by Width
165 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().
166 This function must guarantee that all MMIO read and write operations are serialized.
167
168 @param Address The MMIO register to read.
169 The caller is responsible for aligning the Address if required.
170 @param Width The width of the I/O operation.
171
172 @return Data read from registers in the EFI system memory space.
173
174 **/
175 UINT64
176 EFIAPI
177 MmioWriteWorker (
178 IN UINTN Address,
179 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
180 IN UINT64 Data
181 )
182 {
183 EFI_STATUS Status;
184
185 if (mPciRootBridgeIo != NULL) {
186 Status = mPciRootBridgeIo->Mem.Write (mPciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, Address, 1, &Data);
187 } else {
188 Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);
189 }
190 ASSERT_EFI_ERROR (Status);
191
192 return Data;
193 }
194
195 /**
196 Reads an 8-bit I/O port.
197
198 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
199 This function must guarantee that all I/O read and write operations are
200 serialized.
201
202 If 8-bit I/O port operations are not supported, then ASSERT().
203
204 @param Port The I/O port to read.
205
206 @return The value read.
207
208 **/
209 UINT8
210 EFIAPI
211 IoRead8 (
212 IN UINTN Port
213 )
214 {
215 return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);
216 }
217
218 /**
219 Writes an 8-bit I/O port.
220
221 Writes the 8-bit I/O port specified by Port with the value specified by Value
222 and returns Value. This function must guarantee that all I/O read and write
223 operations are serialized.
224
225 If 8-bit I/O port operations are not supported, then ASSERT().
226
227 @param Port The I/O port to write.
228 @param Value The value to write to the I/O port.
229
230 @return The value written the I/O port.
231
232 **/
233 UINT8
234 EFIAPI
235 IoWrite8 (
236 IN UINTN Port,
237 IN UINT8 Value
238 )
239 {
240 return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);
241 }
242
243 /**
244 Reads a 16-bit I/O port.
245
246 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
247 This function must guarantee that all I/O read and write operations are
248 serialized.
249
250 If 16-bit I/O port operations are not supported, then ASSERT().
251
252 @param Port The I/O port to read.
253
254 @return The value read.
255
256 **/
257 UINT16
258 EFIAPI
259 IoRead16 (
260 IN UINTN Port
261 )
262 {
263 //
264 // Make sure Port is aligned on a 16-bit boundary.
265 //
266 ASSERT ((Port & 1) == 0);
267 return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);
268 }
269
270 /**
271 Writes a 16-bit I/O port.
272
273 Writes the 16-bit I/O port specified by Port with the value specified by Value
274 and returns Value. This function must guarantee that all I/O read and write
275 operations are serialized.
276
277 If 16-bit I/O port operations are not supported, then ASSERT().
278
279 @param Port The I/O port to write.
280 @param Value The value to write to the I/O port.
281
282 @return The value written the I/O port.
283
284 **/
285 UINT16
286 EFIAPI
287 IoWrite16 (
288 IN UINTN Port,
289 IN UINT16 Value
290 )
291 {
292 //
293 // Make sure Port is aligned on a 16-bit boundary.
294 //
295 ASSERT ((Port & 1) == 0);
296 return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);
297 }
298
299 /**
300 Reads a 32-bit I/O port.
301
302 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
303 This function must guarantee that all I/O read and write operations are
304 serialized.
305
306 If 32-bit I/O port operations are not supported, then ASSERT().
307
308 @param Port The I/O port to read.
309
310 @return The value read.
311
312 **/
313 UINT32
314 EFIAPI
315 IoRead32 (
316 IN UINTN Port
317 )
318 {
319 //
320 // Make sure Port is aligned on a 32-bit boundary.
321 //
322 ASSERT ((Port & 3) == 0);
323 return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);
324 }
325
326 /**
327 Writes a 32-bit I/O port.
328
329 Writes the 32-bit I/O port specified by Port with the value specified by Value
330 and returns Value. This function must guarantee that all I/O read and write
331 operations are serialized.
332
333 If 32-bit I/O port operations are not supported, then ASSERT().
334
335 @param Port The I/O port to write.
336 @param Value The value to write to the I/O port.
337
338 @return The value written the I/O port.
339
340 **/
341 UINT32
342 EFIAPI
343 IoWrite32 (
344 IN UINTN Port,
345 IN UINT32 Value
346 )
347 {
348 //
349 // Make sure Port is aligned on a 32-bit boundary.
350 //
351 ASSERT ((Port & 3) == 0);
352 return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);
353 }
354
355 /**
356 Reads a 64-bit I/O port.
357
358 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
359 This function must guarantee that all I/O read and write operations are
360 serialized.
361
362 If 64-bit I/O port operations are not supported, then ASSERT().
363
364 @param Port The I/O port to read.
365
366 @return The value read.
367
368 **/
369 UINT64
370 EFIAPI
371 IoRead64 (
372 IN UINTN Port
373 )
374 {
375 //
376 // Make sure Port is aligned on a 64-bit boundary.
377 //
378 ASSERT ((Port & 7) == 0);
379 return IoReadWorker (Port, EfiCpuIoWidthUint64);
380 }
381
382 /**
383 Writes a 64-bit I/O port.
384
385 Writes the 64-bit I/O port specified by Port with the value specified by Value
386 and returns Value. This function must guarantee that all I/O read and write
387 operations are serialized.
388
389 If 64-bit I/O port operations are not supported, then ASSERT().
390
391 @param Port The I/O port to write.
392 @param Value The value to write to the I/O port.
393
394 @return The value written the I/O port.
395
396 **/
397 UINT64
398 EFIAPI
399 IoWrite64 (
400 IN UINTN Port,
401 IN UINT64 Value
402 )
403 {
404 //
405 // Make sure Port is aligned on a 64-bit boundary.
406 //
407 ASSERT ((Port & 7) == 0);
408 return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);
409 }
410
411 /**
412 Reads an 8-bit MMIO register.
413
414 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
415 returned. This function must guarantee that all MMIO read and write
416 operations are serialized.
417
418 If 8-bit MMIO register operations are not supported, then ASSERT().
419
420 @param Address The MMIO register to read.
421
422 @return The value read.
423
424 **/
425 UINT8
426 EFIAPI
427 MmioRead8 (
428 IN UINTN Address
429 )
430 {
431 return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);
432 }
433
434 /**
435 Writes an 8-bit MMIO register.
436
437 Writes the 8-bit MMIO register specified by Address with the value specified
438 by Value and returns Value. This function must guarantee that all MMIO read
439 and write operations are serialized.
440
441 If 8-bit MMIO register operations are not supported, then ASSERT().
442
443 @param Address The MMIO register to write.
444 @param Value The value to write to the MMIO register.
445
446 **/
447 UINT8
448 EFIAPI
449 MmioWrite8 (
450 IN UINTN Address,
451 IN UINT8 Value
452 )
453 {
454 return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);
455 }
456
457 /**
458 Reads a 16-bit MMIO register.
459
460 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
461 returned. This function must guarantee that all MMIO read and write
462 operations are serialized.
463
464 If 16-bit MMIO register operations are not supported, then ASSERT().
465
466 @param Address The MMIO register to read.
467
468 @return The value read.
469
470 **/
471 UINT16
472 EFIAPI
473 MmioRead16 (
474 IN UINTN Address
475 )
476 {
477 //
478 // Make sure Address is aligned on a 16-bit boundary.
479 //
480 ASSERT ((Address & 1) == 0);
481 return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);
482 }
483
484 /**
485 Writes a 16-bit MMIO register.
486
487 Writes the 16-bit MMIO register specified by Address with the value specified
488 by Value and returns Value. This function must guarantee that all MMIO read
489 and write operations are serialized.
490
491 If 16-bit MMIO register operations are not supported, then ASSERT().
492
493 @param Address The MMIO register to write.
494 @param Value The value to write to the MMIO register.
495
496 **/
497 UINT16
498 EFIAPI
499 MmioWrite16 (
500 IN UINTN Address,
501 IN UINT16 Value
502 )
503 {
504 //
505 // Make sure Address is aligned on a 16-bit boundary.
506 //
507 ASSERT ((Address & 1) == 0);
508 return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);
509 }
510
511 /**
512 Reads a 32-bit MMIO register.
513
514 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
515 returned. This function must guarantee that all MMIO read and write
516 operations are serialized.
517
518 If 32-bit MMIO register operations are not supported, then ASSERT().
519
520 @param Address The MMIO register to read.
521
522 @return The value read.
523
524 **/
525 UINT32
526 EFIAPI
527 MmioRead32 (
528 IN UINTN Address
529 )
530 {
531 //
532 // Make sure Address is aligned on a 32-bit boundary.
533 //
534 ASSERT ((Address & 3) == 0);
535 return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);
536 }
537
538 /**
539 Writes a 32-bit MMIO register.
540
541 Writes the 32-bit MMIO register specified by Address with the value specified
542 by Value and returns Value. This function must guarantee that all MMIO read
543 and write operations are serialized.
544
545 If 32-bit MMIO register operations are not supported, then ASSERT().
546
547 @param Address The MMIO register to write.
548 @param Value The value to write to the MMIO register.
549
550 **/
551 UINT32
552 EFIAPI
553 MmioWrite32 (
554 IN UINTN Address,
555 IN UINT32 Value
556 )
557 {
558 //
559 // Make sure Address is aligned on a 32-bit boundary.
560 //
561 ASSERT ((Address & 3) == 0);
562 return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);
563 }
564
565 /**
566 Reads a 64-bit MMIO register.
567
568 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
569 returned. This function must guarantee that all MMIO read and write
570 operations are serialized.
571
572 If 64-bit MMIO register operations are not supported, then ASSERT().
573
574 @param Address The MMIO register to read.
575
576 @return The value read.
577
578 **/
579 UINT64
580 EFIAPI
581 MmioRead64 (
582 IN UINTN Address
583 )
584 {
585 //
586 // Make sure Address is aligned on a 64-bit boundary.
587 //
588 ASSERT ((Address & 7) == 0);
589 return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);
590 }
591
592 /**
593 Writes a 64-bit MMIO register.
594
595 Writes the 64-bit MMIO register specified by Address with the value specified
596 by Value and returns Value. This function must guarantee that all MMIO read
597 and write operations are serialized.
598
599 If 64-bit MMIO register operations are not supported, then ASSERT().
600
601 @param Address The MMIO register to write.
602 @param Value The value to write to the MMIO register.
603
604 **/
605 UINT64
606 EFIAPI
607 MmioWrite64 (
608 IN UINTN Address,
609 IN UINT64 Value
610 )
611 {
612 //
613 // Make sure Address is aligned on a 64-bit boundary.
614 //
615 ASSERT ((Address & 7) == 0);
616 return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);
617 }