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