Fix typo in comment.
[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 @param Data The value to write to the I/O port.
172
173 @return Data read from registers in the EFI system memory space.
174
175 **/
176 UINT64
177 EFIAPI
178 MmioWriteWorker (
179 IN UINTN Address,
180 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
181 IN UINT64 Data
182 )
183 {
184 EFI_STATUS Status;
185
186 if (mPciRootBridgeIo != NULL) {
187 Status = mPciRootBridgeIo->Mem.Write (mPciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, Address, 1, &Data);
188 } else {
189 Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);
190 }
191 ASSERT_EFI_ERROR (Status);
192
193 return Data;
194 }
195
196 /**
197 Reads an 8-bit I/O port.
198
199 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
200 This function must guarantee that all I/O read and write operations are
201 serialized.
202
203 If 8-bit I/O port operations are not supported, then ASSERT().
204
205 @param Port The I/O port to read.
206
207 @return The value read.
208
209 **/
210 UINT8
211 EFIAPI
212 IoRead8 (
213 IN UINTN Port
214 )
215 {
216 return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);
217 }
218
219 /**
220 Writes an 8-bit I/O port.
221
222 Writes the 8-bit I/O port specified by Port with the value specified by Value
223 and returns Value. This function must guarantee that all I/O read and write
224 operations are serialized.
225
226 If 8-bit I/O port operations are not supported, then ASSERT().
227
228 @param Port The I/O port to write.
229 @param Value The value to write to the I/O port.
230
231 @return The value written the I/O port.
232
233 **/
234 UINT8
235 EFIAPI
236 IoWrite8 (
237 IN UINTN Port,
238 IN UINT8 Value
239 )
240 {
241 return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);
242 }
243
244 /**
245 Reads a 16-bit I/O port.
246
247 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
248 This function must guarantee that all I/O read and write operations are
249 serialized.
250
251 If 16-bit I/O port operations are not supported, then ASSERT().
252
253 @param Port The I/O port to read.
254
255 @return The value read.
256
257 **/
258 UINT16
259 EFIAPI
260 IoRead16 (
261 IN UINTN Port
262 )
263 {
264 //
265 // Make sure Port is aligned on a 16-bit boundary.
266 //
267 ASSERT ((Port & 1) == 0);
268 return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);
269 }
270
271 /**
272 Writes a 16-bit I/O port.
273
274 Writes the 16-bit I/O port specified by Port with the value specified by Value
275 and returns Value. This function must guarantee that all I/O read and write
276 operations are serialized.
277
278 If 16-bit I/O port operations are not supported, then ASSERT().
279
280 @param Port The I/O port to write.
281 @param Value The value to write to the I/O port.
282
283 @return The value written the I/O port.
284
285 **/
286 UINT16
287 EFIAPI
288 IoWrite16 (
289 IN UINTN Port,
290 IN UINT16 Value
291 )
292 {
293 //
294 // Make sure Port is aligned on a 16-bit boundary.
295 //
296 ASSERT ((Port & 1) == 0);
297 return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);
298 }
299
300 /**
301 Reads a 32-bit I/O port.
302
303 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
304 This function must guarantee that all I/O read and write operations are
305 serialized.
306
307 If 32-bit I/O port operations are not supported, then ASSERT().
308
309 @param Port The I/O port to read.
310
311 @return The value read.
312
313 **/
314 UINT32
315 EFIAPI
316 IoRead32 (
317 IN UINTN Port
318 )
319 {
320 //
321 // Make sure Port is aligned on a 32-bit boundary.
322 //
323 ASSERT ((Port & 3) == 0);
324 return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);
325 }
326
327 /**
328 Writes a 32-bit I/O port.
329
330 Writes the 32-bit I/O port specified by Port with the value specified by Value
331 and returns Value. This function must guarantee that all I/O read and write
332 operations are serialized.
333
334 If 32-bit I/O port operations are not supported, then ASSERT().
335
336 @param Port The I/O port to write.
337 @param Value The value to write to the I/O port.
338
339 @return The value written the I/O port.
340
341 **/
342 UINT32
343 EFIAPI
344 IoWrite32 (
345 IN UINTN Port,
346 IN UINT32 Value
347 )
348 {
349 //
350 // Make sure Port is aligned on a 32-bit boundary.
351 //
352 ASSERT ((Port & 3) == 0);
353 return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);
354 }
355
356 /**
357 Reads a 64-bit I/O port.
358
359 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
360 This function must guarantee that all I/O read and write operations are
361 serialized.
362
363 If 64-bit I/O port operations are not supported, then ASSERT().
364
365 @param Port The I/O port to read.
366
367 @return The value read.
368
369 **/
370 UINT64
371 EFIAPI
372 IoRead64 (
373 IN UINTN Port
374 )
375 {
376 //
377 // Make sure Port is aligned on a 64-bit boundary.
378 //
379 ASSERT ((Port & 7) == 0);
380 return IoReadWorker (Port, EfiCpuIoWidthUint64);
381 }
382
383 /**
384 Writes a 64-bit I/O port.
385
386 Writes the 64-bit I/O port specified by Port with the value specified by Value
387 and returns Value. This function must guarantee that all I/O read and write
388 operations are serialized.
389
390 If 64-bit I/O port operations are not supported, then ASSERT().
391
392 @param Port The I/O port to write.
393 @param Value The value to write to the I/O port.
394
395 @return The value written the I/O port.
396
397 **/
398 UINT64
399 EFIAPI
400 IoWrite64 (
401 IN UINTN Port,
402 IN UINT64 Value
403 )
404 {
405 //
406 // Make sure Port is aligned on a 64-bit boundary.
407 //
408 ASSERT ((Port & 7) == 0);
409 return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);
410 }
411
412 /**
413 Reads an 8-bit MMIO register.
414
415 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
416 returned. This function must guarantee that all MMIO read and write
417 operations are serialized.
418
419 If 8-bit MMIO register operations are not supported, then ASSERT().
420
421 @param Address The MMIO register to read.
422
423 @return The value read.
424
425 **/
426 UINT8
427 EFIAPI
428 MmioRead8 (
429 IN UINTN Address
430 )
431 {
432 return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);
433 }
434
435 /**
436 Writes an 8-bit MMIO register.
437
438 Writes the 8-bit MMIO register specified by Address with the value specified
439 by Value and returns Value. This function must guarantee that all MMIO read
440 and write operations are serialized.
441
442 If 8-bit MMIO register operations are not supported, then ASSERT().
443
444 @param Address The MMIO register to write.
445 @param Value The value to write to the MMIO register.
446
447 **/
448 UINT8
449 EFIAPI
450 MmioWrite8 (
451 IN UINTN Address,
452 IN UINT8 Value
453 )
454 {
455 return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);
456 }
457
458 /**
459 Reads a 16-bit MMIO register.
460
461 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
462 returned. This function must guarantee that all MMIO read and write
463 operations are serialized.
464
465 If 16-bit MMIO register operations are not supported, then ASSERT().
466
467 @param Address The MMIO register to read.
468
469 @return The value read.
470
471 **/
472 UINT16
473 EFIAPI
474 MmioRead16 (
475 IN UINTN Address
476 )
477 {
478 //
479 // Make sure Address is aligned on a 16-bit boundary.
480 //
481 ASSERT ((Address & 1) == 0);
482 return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);
483 }
484
485 /**
486 Writes a 16-bit MMIO register.
487
488 Writes the 16-bit MMIO register specified by Address with the value specified
489 by Value and returns Value. This function must guarantee that all MMIO read
490 and write operations are serialized.
491
492 If 16-bit MMIO register operations are not supported, then ASSERT().
493
494 @param Address The MMIO register to write.
495 @param Value The value to write to the MMIO register.
496
497 **/
498 UINT16
499 EFIAPI
500 MmioWrite16 (
501 IN UINTN Address,
502 IN UINT16 Value
503 )
504 {
505 //
506 // Make sure Address is aligned on a 16-bit boundary.
507 //
508 ASSERT ((Address & 1) == 0);
509 return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);
510 }
511
512 /**
513 Reads a 32-bit MMIO register.
514
515 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
516 returned. This function must guarantee that all MMIO read and write
517 operations are serialized.
518
519 If 32-bit MMIO register operations are not supported, then ASSERT().
520
521 @param Address The MMIO register to read.
522
523 @return The value read.
524
525 **/
526 UINT32
527 EFIAPI
528 MmioRead32 (
529 IN UINTN Address
530 )
531 {
532 //
533 // Make sure Address is aligned on a 32-bit boundary.
534 //
535 ASSERT ((Address & 3) == 0);
536 return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);
537 }
538
539 /**
540 Writes a 32-bit MMIO register.
541
542 Writes the 32-bit MMIO register specified by Address with the value specified
543 by Value and returns Value. This function must guarantee that all MMIO read
544 and write operations are serialized.
545
546 If 32-bit MMIO register operations are not supported, then ASSERT().
547
548 @param Address The MMIO register to write.
549 @param Value The value to write to the MMIO register.
550
551 **/
552 UINT32
553 EFIAPI
554 MmioWrite32 (
555 IN UINTN Address,
556 IN UINT32 Value
557 )
558 {
559 //
560 // Make sure Address is aligned on a 32-bit boundary.
561 //
562 ASSERT ((Address & 3) == 0);
563 return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);
564 }
565
566 /**
567 Reads a 64-bit MMIO register.
568
569 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
570 returned. This function must guarantee that all MMIO read and write
571 operations are serialized.
572
573 If 64-bit MMIO register operations are not supported, then ASSERT().
574
575 @param Address The MMIO register to read.
576
577 @return The value read.
578
579 **/
580 UINT64
581 EFIAPI
582 MmioRead64 (
583 IN UINTN Address
584 )
585 {
586 //
587 // Make sure Address is aligned on a 64-bit boundary.
588 //
589 ASSERT ((Address & 7) == 0);
590 return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);
591 }
592
593 /**
594 Writes a 64-bit MMIO register.
595
596 Writes the 64-bit MMIO register specified by Address with the value specified
597 by Value and returns Value. This function must guarantee that all MMIO read
598 and write operations are serialized.
599
600 If 64-bit MMIO register operations are not supported, then ASSERT().
601
602 @param Address The MMIO register to write.
603 @param Value The value to write to the MMIO register.
604
605 **/
606 UINT64
607 EFIAPI
608 MmioWrite64 (
609 IN UINTN Address,
610 IN UINT64 Value
611 )
612 {
613 //
614 // Make sure Address is aligned on a 64-bit boundary.
615 //
616 ASSERT ((Address & 7) == 0);
617 return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);
618 }