VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/CpuIoPei/CpuIoPei.c@ 79205

Last change on this file since 79205 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

  • Property svn:eol-style set to native
File size: 26.4 KB
Line 
1/** @file
2 Produces the CPU I/O PPI.
3
4Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
5Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
6
7This program and the accompanying materials
8are licensed and made available under the terms and conditions of the BSD License
9which accompanies this distribution. The full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17#include "CpuIoPei.h"
18
19//
20// Instance of CPU I/O PPI
21//
22EFI_PEI_CPU_IO_PPI gCpuIoPpi = {
23 {
24 CpuMemoryServiceRead,
25 CpuMemoryServiceWrite
26 },
27 {
28 CpuIoServiceRead,
29 CpuIoServiceWrite
30 },
31 CpuIoRead8,
32 CpuIoRead16,
33 CpuIoRead32,
34 CpuIoRead64,
35 CpuIoWrite8,
36 CpuIoWrite16,
37 CpuIoWrite32,
38 CpuIoWrite64,
39 CpuMemRead8,
40 CpuMemRead16,
41 CpuMemRead32,
42 CpuMemRead64,
43 CpuMemWrite8,
44 CpuMemWrite16,
45 CpuMemWrite32,
46 CpuMemWrite64
47};
48
49//
50// PPI Descriptor used to install the CPU I/O PPI
51//
52EFI_PEI_PPI_DESCRIPTOR gPpiList = {
53 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
54 &gEfiPeiCpuIoPpiInstalledGuid,
55 NULL
56};
57
58//
59// Lookup table for increment values based on transfer widths
60//
61UINT8 mInStride[] = {
62 1, // EfiPeiCpuIoWidthUint8
63 2, // EfiPeiCpuIoWidthUint16
64 4, // EfiPeiCpuIoWidthUint32
65 8, // EfiPeiCpuIoWidthUint64
66 0, // EfiPeiCpuIoWidthFifoUint8
67 0, // EfiPeiCpuIoWidthFifoUint16
68 0, // EfiPeiCpuIoWidthFifoUint32
69 0, // EfiPeiCpuIoWidthFifoUint64
70 1, // EfiPeiCpuIoWidthFillUint8
71 2, // EfiPeiCpuIoWidthFillUint16
72 4, // EfiPeiCpuIoWidthFillUint32
73 8 // EfiPeiCpuIoWidthFillUint64
74};
75
76//
77// Lookup table for increment values based on transfer widths
78//
79UINT8 mOutStride[] = {
80 1, // EfiPeiCpuIoWidthUint8
81 2, // EfiPeiCpuIoWidthUint16
82 4, // EfiPeiCpuIoWidthUint32
83 8, // EfiPeiCpuIoWidthUint64
84 1, // EfiPeiCpuIoWidthFifoUint8
85 2, // EfiPeiCpuIoWidthFifoUint16
86 4, // EfiPeiCpuIoWidthFifoUint32
87 8, // EfiPeiCpuIoWidthFifoUint64
88 0, // EfiPeiCpuIoWidthFillUint8
89 0, // EfiPeiCpuIoWidthFillUint16
90 0, // EfiPeiCpuIoWidthFillUint32
91 0 // EfiPeiCpuIoWidthFillUint64
92};
93
94/**
95 Check parameters to a CPU I/O PPI service request.
96
97 @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
98 @param[in] Width The width of the access. Enumerated in bytes.
99 @param[in] Address The physical address of the access.
100 @param[in] Count The number of accesses to perform.
101 @param[in] Buffer A pointer to the buffer of data.
102
103 @retval EFI_SUCCESS The parameters for this request pass the checks.
104 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
105 @retval EFI_INVALID_PARAMETER Buffer is NULL.
106 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
107 and Count is not valid for this EFI system.
108
109**/
110EFI_STATUS
111CpuIoCheckParameter (
112 IN BOOLEAN MmioOperation,
113 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
114 IN UINT64 Address,
115 IN UINTN Count,
116 IN VOID *Buffer
117 )
118{
119 UINT64 MaxCount;
120 UINT64 Limit;
121
122 //
123 // Check to see if Buffer is NULL
124 //
125 if (Buffer == NULL) {
126 return EFI_INVALID_PARAMETER;
127 }
128
129 //
130 // Check to see if Width is in the valid range
131 //
132 if ((UINT32)Width >= EfiPeiCpuIoWidthMaximum) {
133 return EFI_INVALID_PARAMETER;
134 }
135
136 //
137 // For FIFO type, the target address won't increase during the access,
138 // so treat Count as 1
139 //
140 if (Width >= EfiPeiCpuIoWidthFifoUint8 && Width <= EfiPeiCpuIoWidthFifoUint64) {
141 Count = 1;
142 }
143
144 //
145 // Check to see if Width is in the valid range for I/O Port operations
146 //
147 Width = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
148 if (!MmioOperation && (Width == EfiPeiCpuIoWidthUint64)) {
149 return EFI_INVALID_PARAMETER;
150 }
151
152 //
153 // Check to see if any address associated with this transfer exceeds the maximum
154 // allowed address. The maximum address implied by the parameters passed in is
155 // Address + Size * Count. If the following condition is met, then the transfer
156 // is not supported.
157 //
158 // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
159 //
160 // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
161 // can also be the maximum integer value supported by the CPU, this range
162 // check must be adjusted to avoid all overflow conditions.
163 //
164 // The following form of the range check is equivalent but assumes that
165 // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
166 //
167 Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
168 if (Count == 0) {
169 if (Address > Limit) {
170 return EFI_UNSUPPORTED;
171 }
172 } else {
173 MaxCount = RShiftU64 (Limit, Width);
174 if (MaxCount < (Count - 1)) {
175 return EFI_UNSUPPORTED;
176 }
177 if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
178 return EFI_UNSUPPORTED;
179 }
180 }
181
182 return EFI_SUCCESS;
183}
184
185/**
186 Reads memory-mapped registers.
187
188 @param[in] PeiServices An indirect pointer to the PEI Services Table
189 published by the PEI Foundation.
190 @param[in] This Pointer to local data for the interface.
191 @param[in] Width The width of the access. Enumerated in bytes.
192 @param[in] Address The physical address of the access.
193 @param[in] Count The number of accesses to perform.
194 @param[out] Buffer A pointer to the buffer of data.
195
196 @retval EFI_SUCCESS The function completed successfully.
197 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
198 @retval EFI_INVALID_PARAMETER Buffer is NULL.
199 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
200 and Count is not valid for this EFI system.
201
202**/
203EFI_STATUS
204EFIAPI
205CpuMemoryServiceRead (
206 IN CONST EFI_PEI_SERVICES **PeiServices,
207 IN CONST EFI_PEI_CPU_IO_PPI *This,
208 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
209 IN UINT64 Address,
210 IN UINTN Count,
211 OUT VOID *Buffer
212 )
213{
214 EFI_STATUS Status;
215 UINT8 InStride;
216 UINT8 OutStride;
217 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
218 BOOLEAN Aligned;
219 UINT8 *Uint8Buffer;
220
221 Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
222 if (EFI_ERROR (Status)) {
223 return Status;
224 }
225
226 //
227 // Select loop based on the width of the transfer
228 //
229 InStride = mInStride[Width];
230 OutStride = mOutStride[Width];
231 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
232 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
233 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
234 if (OperationWidth == EfiPeiCpuIoWidthUint8) {
235 *Uint8Buffer = MmioRead8 ((UINTN)Address);
236 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
237 if (Aligned) {
238 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
239 } else {
240 WriteUnaligned16 ((UINT16 *)Uint8Buffer, MmioRead16 ((UINTN)Address));
241 }
242 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
243 if (Aligned) {
244 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
245 } else {
246 WriteUnaligned32 ((UINT32 *)Uint8Buffer, MmioRead32 ((UINTN)Address));
247 }
248 } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {
249 if (Aligned) {
250 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
251 } else {
252 WriteUnaligned64 ((UINT64 *)Uint8Buffer, MmioRead64 ((UINTN)Address));
253 }
254 }
255 }
256 return EFI_SUCCESS;
257}
258
259/**
260 Writes memory-mapped registers.
261
262 @param[in] PeiServices An indirect pointer to the PEI Services Table
263 published by the PEI Foundation.
264 @param[in] This Pointer to local data for the interface.
265 @param[in] Width The width of the access. Enumerated in bytes.
266 @param[in] Address The physical address of the access.
267 @param[in] Count The number of accesses to perform.
268 @param[in] Buffer A pointer to the buffer of data.
269
270 @retval EFI_SUCCESS The function completed successfully.
271 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
272 @retval EFI_INVALID_PARAMETER Buffer is NULL.
273 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
274 and Count is not valid for this EFI system.
275
276**/
277EFI_STATUS
278EFIAPI
279CpuMemoryServiceWrite (
280 IN CONST EFI_PEI_SERVICES **PeiServices,
281 IN CONST EFI_PEI_CPU_IO_PPI *This,
282 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
283 IN UINT64 Address,
284 IN UINTN Count,
285 IN VOID *Buffer
286 )
287{
288 EFI_STATUS Status;
289 UINT8 InStride;
290 UINT8 OutStride;
291 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
292 BOOLEAN Aligned;
293 UINT8 *Uint8Buffer;
294
295 Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
296 if (EFI_ERROR (Status)) {
297 return Status;
298 }
299
300 //
301 // Select loop based on the width of the transfer
302 //
303 InStride = mInStride[Width];
304 OutStride = mOutStride[Width];
305 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
306 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
307 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
308 if (OperationWidth == EfiPeiCpuIoWidthUint8) {
309 MmioWrite8 ((UINTN)Address, *Uint8Buffer);
310 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
311 if (Aligned) {
312 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
313 } else {
314 MmioWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
315 }
316 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
317 if (Aligned) {
318 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
319 } else {
320 MmioWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
321 }
322 } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {
323 if (Aligned) {
324 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
325 } else {
326 MmioWrite64 ((UINTN)Address, ReadUnaligned64 ((UINT64 *)Uint8Buffer));
327 }
328 }
329 }
330 return EFI_SUCCESS;
331}
332
333/**
334 Reads I/O registers.
335
336 @param[in] PeiServices An indirect pointer to the PEI Services Table
337 published by the PEI Foundation.
338 @param[in] This Pointer to local data for the interface.
339 @param[in] Width The width of the access. Enumerated in bytes.
340 @param[in] Address The physical address of the access.
341 @param[in] Count The number of accesses to perform.
342 @param[out] Buffer A pointer to the buffer of data.
343
344 @retval EFI_SUCCESS The function completed successfully.
345 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
346 @retval EFI_INVALID_PARAMETER Buffer is NULL.
347 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
348 and Count is not valid for this EFI system.
349
350**/
351EFI_STATUS
352EFIAPI
353CpuIoServiceRead (
354 IN CONST EFI_PEI_SERVICES **PeiServices,
355 IN CONST EFI_PEI_CPU_IO_PPI *This,
356 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
357 IN UINT64 Address,
358 IN UINTN Count,
359 OUT VOID *Buffer
360 )
361{
362 EFI_STATUS Status;
363 UINT8 InStride;
364 UINT8 OutStride;
365 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
366 BOOLEAN Aligned;
367 UINT8 *Uint8Buffer;
368
369 Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
370 if (EFI_ERROR (Status)) {
371 return Status;
372 }
373
374 //
375 // Select loop based on the width of the transfer
376 //
377 InStride = mInStride[Width];
378 OutStride = mOutStride[Width];
379 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
380
381 //
382 // Fifo operations supported for (mInStride[Width] == 0)
383 //
384 if (InStride == 0) {
385 switch (OperationWidth) {
386 case EfiPeiCpuIoWidthUint8:
387 IoReadFifo8 ((UINTN)Address, Count, Buffer);
388 return EFI_SUCCESS;
389 case EfiPeiCpuIoWidthUint16:
390 IoReadFifo16 ((UINTN)Address, Count, Buffer);
391 return EFI_SUCCESS;
392 case EfiPeiCpuIoWidthUint32:
393 IoReadFifo32 ((UINTN)Address, Count, Buffer);
394 return EFI_SUCCESS;
395 default:
396 //
397 // The CpuIoCheckParameter call above will ensure that this
398 // path is not taken.
399 //
400 ASSERT (FALSE);
401 break;
402 }
403 }
404
405 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
406 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
407 if (OperationWidth == EfiPeiCpuIoWidthUint8) {
408 *Uint8Buffer = IoRead8 ((UINTN)Address);
409 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
410 if (Aligned) {
411 *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
412 } else {
413 WriteUnaligned16 ((UINT16 *)Uint8Buffer, IoRead16 ((UINTN)Address));
414 }
415 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
416 if (Aligned) {
417 *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
418 } else {
419 WriteUnaligned32 ((UINT32 *)Uint8Buffer, IoRead32 ((UINTN)Address));
420 }
421 }
422 }
423
424 return EFI_SUCCESS;
425}
426
427/**
428 Write I/O registers.
429
430 @param[in] PeiServices An indirect pointer to the PEI Services Table
431 published by the PEI Foundation.
432 @param[in] This Pointer to local data for the interface.
433 @param[in] Width The width of the access. Enumerated in bytes.
434 @param[in] Address The physical address of the access.
435 @param[in] Count The number of accesses to perform.
436 @param[in] Buffer A pointer to the buffer of data.
437
438 @retval EFI_SUCCESS The function completed successfully.
439 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
440 @retval EFI_INVALID_PARAMETER Buffer is NULL.
441 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
442 and Count is not valid for this EFI system.
443
444**/
445EFI_STATUS
446EFIAPI
447CpuIoServiceWrite (
448 IN CONST EFI_PEI_SERVICES **PeiServices,
449 IN CONST EFI_PEI_CPU_IO_PPI *This,
450 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
451 IN UINT64 Address,
452 IN UINTN Count,
453 IN VOID *Buffer
454 )
455{
456 EFI_STATUS Status;
457 UINT8 InStride;
458 UINT8 OutStride;
459 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
460 BOOLEAN Aligned;
461 UINT8 *Uint8Buffer;
462
463 //
464 // Make sure the parameters are valid
465 //
466 Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
467 if (EFI_ERROR (Status)) {
468 return Status;
469 }
470
471 //
472 // Select loop based on the width of the transfer
473 //
474 InStride = mInStride[Width];
475 OutStride = mOutStride[Width];
476 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
477
478 //
479 // Fifo operations supported for (mInStride[Width] == 0)
480 //
481 if (InStride == 0) {
482 switch (OperationWidth) {
483 case EfiPeiCpuIoWidthUint8:
484 IoWriteFifo8 ((UINTN)Address, Count, Buffer);
485 return EFI_SUCCESS;
486 case EfiPeiCpuIoWidthUint16:
487 IoWriteFifo16 ((UINTN)Address, Count, Buffer);
488 return EFI_SUCCESS;
489 case EfiPeiCpuIoWidthUint32:
490 IoWriteFifo32 ((UINTN)Address, Count, Buffer);
491 return EFI_SUCCESS;
492 default:
493 //
494 // The CpuIoCheckParameter call above will ensure that this
495 // path is not taken.
496 //
497 ASSERT (FALSE);
498 break;
499 }
500 }
501
502 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
503 for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
504 if (OperationWidth == EfiPeiCpuIoWidthUint8) {
505 IoWrite8 ((UINTN)Address, *Uint8Buffer);
506 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
507 if (Aligned) {
508 IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
509 } else {
510 IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
511 }
512 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
513 if (Aligned) {
514 IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
515 } else {
516 IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
517 }
518 }
519 }
520
521 return EFI_SUCCESS;
522}
523
524/**
525 8-bit I/O read operations.
526
527 @param[in] PeiServices An indirect pointer to the PEI Services Table published
528 by the PEI Foundation.
529 @param[in] This Pointer to local data for the interface.
530 @param[in] Address The physical address of the access.
531
532 @return An 8-bit value returned from the I/O space.
533**/
534UINT8
535EFIAPI
536CpuIoRead8 (
537 IN CONST EFI_PEI_SERVICES **PeiServices,
538 IN CONST EFI_PEI_CPU_IO_PPI *This,
539 IN UINT64 Address
540 )
541{
542 return IoRead8 ((UINTN)Address);
543}
544
545/**
546 16-bit I/O read operations.
547
548 @param[in] PeiServices An indirect pointer to the PEI Services Table published
549 by the PEI Foundation.
550 @param[in] This Pointer to local data for the interface.
551 @param[in] Address The physical address of the access.
552
553 @return A 16-bit value returned from the I/O space.
554
555**/
556UINT16
557EFIAPI
558CpuIoRead16 (
559 IN CONST EFI_PEI_SERVICES **PeiServices,
560 IN CONST EFI_PEI_CPU_IO_PPI *This,
561 IN UINT64 Address
562 )
563{
564 return IoRead16 ((UINTN)Address);
565}
566
567/**
568 32-bit I/O read operations.
569
570 @param[in] PeiServices An indirect pointer to the PEI Services Table published
571 by the PEI Foundation.
572 @param[in] This Pointer to local data for the interface.
573 @param[in] Address The physical address of the access.
574
575 @return A 32-bit value returned from the I/O space.
576
577**/
578UINT32
579EFIAPI
580CpuIoRead32 (
581 IN CONST EFI_PEI_SERVICES **PeiServices,
582 IN CONST EFI_PEI_CPU_IO_PPI *This,
583 IN UINT64 Address
584 )
585{
586 return IoRead32 ((UINTN)Address);
587}
588
589/**
590 64-bit I/O read operations.
591
592 @param[in] PeiServices An indirect pointer to the PEI Services Table published
593 by the PEI Foundation.
594 @param[in] This Pointer to local data for the interface.
595 @param[in] Address The physical address of the access.
596
597 @return A 64-bit value returned from the I/O space.
598
599**/
600UINT64
601EFIAPI
602CpuIoRead64 (
603 IN CONST EFI_PEI_SERVICES **PeiServices,
604 IN CONST EFI_PEI_CPU_IO_PPI *This,
605 IN UINT64 Address
606 )
607{
608 return IoRead64 ((UINTN)Address);
609}
610
611/**
612 8-bit I/O write operations.
613
614 @param[in] PeiServices An indirect pointer to the PEI Services Table published
615 by the PEI Foundation.
616 @param[in] This Pointer to local data for the interface.
617 @param[in] Address The physical address of the access.
618 @param[in] Data The data to write.
619
620**/
621VOID
622EFIAPI
623CpuIoWrite8 (
624 IN CONST EFI_PEI_SERVICES **PeiServices,
625 IN CONST EFI_PEI_CPU_IO_PPI *This,
626 IN UINT64 Address,
627 IN UINT8 Data
628 )
629{
630 IoWrite8 ((UINTN)Address, Data);
631}
632
633/**
634 16-bit I/O write operations.
635
636 @param[in] PeiServices An indirect pointer to the PEI Services Table published
637 by the PEI Foundation.
638 @param[in] This Pointer to local data for the interface.
639 @param[in] Address The physical address of the access.
640 @param[in] Data The data to write.
641
642**/
643VOID
644EFIAPI
645CpuIoWrite16 (
646 IN CONST EFI_PEI_SERVICES **PeiServices,
647 IN CONST EFI_PEI_CPU_IO_PPI *This,
648 IN UINT64 Address,
649 IN UINT16 Data
650 )
651{
652 IoWrite16 ((UINTN)Address, Data);
653}
654
655/**
656 32-bit I/O write operations.
657
658 @param[in] PeiServices An indirect pointer to the PEI Services Table published
659 by the PEI Foundation.
660 @param[in] This Pointer to local data for the interface.
661 @param[in] Address The physical address of the access.
662 @param[in] Data The data to write.
663
664**/
665VOID
666EFIAPI
667CpuIoWrite32 (
668 IN CONST EFI_PEI_SERVICES **PeiServices,
669 IN CONST EFI_PEI_CPU_IO_PPI *This,
670 IN UINT64 Address,
671 IN UINT32 Data
672 )
673{
674 IoWrite32 ((UINTN)Address, Data);
675}
676
677/**
678 64-bit I/O write operations.
679
680 @param[in] PeiServices An indirect pointer to the PEI Services Table published
681 by the PEI Foundation.
682 @param[in] This Pointer to local data for the interface.
683 @param[in] Address The physical address of the access.
684 @param[in] Data The data to write.
685
686**/
687VOID
688EFIAPI
689CpuIoWrite64 (
690 IN CONST EFI_PEI_SERVICES **PeiServices,
691 IN CONST EFI_PEI_CPU_IO_PPI *This,
692 IN UINT64 Address,
693 IN UINT64 Data
694 )
695{
696 IoWrite64 ((UINTN)Address, Data);
697}
698
699/**
700 8-bit memory read operations.
701
702 @param[in] PeiServices An indirect pointer to the PEI Services Table published
703 by the PEI Foundation.
704 @param[in] This Pointer to local data for the interface.
705 @param[in] Address The physical address of the access.
706
707 @return An 8-bit value returned from the memory space.
708
709**/
710UINT8
711EFIAPI
712CpuMemRead8 (
713 IN CONST EFI_PEI_SERVICES **PeiServices,
714 IN CONST EFI_PEI_CPU_IO_PPI *This,
715 IN UINT64 Address
716 )
717{
718 return MmioRead8 ((UINTN)Address);
719}
720
721/**
722 16-bit memory read operations.
723
724 @param[in] PeiServices An indirect pointer to the PEI Services Table published
725 by the PEI Foundation.
726 @param[in] This Pointer to local data for the interface.
727 @param[in] Address The physical address of the access.
728
729 @return A 16-bit value returned from the memory space.
730
731**/
732UINT16
733EFIAPI
734CpuMemRead16 (
735 IN CONST EFI_PEI_SERVICES **PeiServices,
736 IN CONST EFI_PEI_CPU_IO_PPI *This,
737 IN UINT64 Address
738 )
739{
740 return MmioRead16 ((UINTN)Address);
741}
742
743/**
744 32-bit memory read operations.
745
746 @param[in] PeiServices An indirect pointer to the PEI Services Table published
747 by the PEI Foundation.
748 @param[in] This Pointer to local data for the interface.
749 @param[in] Address The physical address of the access.
750
751 @return A 32-bit value returned from the memory space.
752
753**/
754UINT32
755EFIAPI
756CpuMemRead32 (
757 IN CONST EFI_PEI_SERVICES **PeiServices,
758 IN CONST EFI_PEI_CPU_IO_PPI *This,
759 IN UINT64 Address
760 )
761{
762 return MmioRead32 ((UINTN)Address);
763}
764
765/**
766 64-bit memory read operations.
767
768 @param[in] PeiServices An indirect pointer to the PEI Services Table published
769 by the PEI Foundation.
770 @param[in] This Pointer to local data for the interface.
771 @param[in] Address The physical address of the access.
772
773 @return A 64-bit value returned from the memory space.
774
775**/
776UINT64
777EFIAPI
778CpuMemRead64 (
779 IN CONST EFI_PEI_SERVICES **PeiServices,
780 IN CONST EFI_PEI_CPU_IO_PPI *This,
781 IN UINT64 Address
782 )
783{
784 return MmioRead64 ((UINTN)Address);
785}
786
787/**
788 8-bit memory write operations.
789
790 @param[in] PeiServices An indirect pointer to the PEI Services Table published
791 by the PEI Foundation.
792 @param[in] This Pointer to local data for the interface.
793 @param[in] Address The physical address of the access.
794 @param[in] Data The data to write.
795
796**/
797VOID
798EFIAPI
799CpuMemWrite8 (
800 IN CONST EFI_PEI_SERVICES **PeiServices,
801 IN CONST EFI_PEI_CPU_IO_PPI *This,
802 IN UINT64 Address,
803 IN UINT8 Data
804 )
805{
806 MmioWrite8 ((UINTN)Address, Data);
807}
808
809/**
810 16-bit memory write operations.
811
812 @param[in] PeiServices An indirect pointer to the PEI Services Table published
813 by the PEI Foundation.
814 @param[in] This Pointer to local data for the interface.
815 @param[in] Address The physical address of the access.
816 @param[in] Data The data to write.
817
818**/
819VOID
820EFIAPI
821CpuMemWrite16 (
822 IN CONST EFI_PEI_SERVICES **PeiServices,
823 IN CONST EFI_PEI_CPU_IO_PPI *This,
824 IN UINT64 Address,
825 IN UINT16 Data
826 )
827{
828 MmioWrite16 ((UINTN)Address, Data);
829}
830
831/**
832 32-bit memory write operations.
833
834 @param[in] PeiServices An indirect pointer to the PEI Services Table published
835 by the PEI Foundation.
836 @param[in] This Pointer to local data for the interface.
837 @param[in] Address The physical address of the access.
838 @param[in] Data The data to write.
839
840**/
841VOID
842EFIAPI
843CpuMemWrite32 (
844 IN CONST EFI_PEI_SERVICES **PeiServices,
845 IN CONST EFI_PEI_CPU_IO_PPI *This,
846 IN UINT64 Address,
847 IN UINT32 Data
848 )
849{
850 MmioWrite32 ((UINTN)Address, Data);
851}
852
853/**
854 64-bit memory write operations.
855
856 @param[in] PeiServices An indirect pointer to the PEI Services Table published
857 by the PEI Foundation.
858 @param[in] This Pointer to local data for the interface.
859 @param[in] Address The physical address of the access.
860 @param[in] Data The data to write.
861
862**/
863VOID
864EFIAPI
865CpuMemWrite64 (
866 IN CONST EFI_PEI_SERVICES **PeiServices,
867 IN CONST EFI_PEI_CPU_IO_PPI *This,
868 IN UINT64 Address,
869 IN UINT64 Data
870 )
871{
872 MmioWrite64 ((UINTN)Address, Data);
873}
874
875/**
876 The Entry point of the CPU I/O PEIM
877
878 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
879
880 @param[in] FileHandle Pointer to image file handle.
881 @param[in] PeiServices Pointer to PEI Services Table
882
883 @retval EFI_SUCCESS CPU I/O PPI successfully installed
884
885**/
886EFI_STATUS
887EFIAPI
888CpuIoInitialize (
889 IN EFI_PEI_FILE_HANDLE FileHandle,
890 IN CONST EFI_PEI_SERVICES **PeiServices
891 )
892{
893 EFI_STATUS Status;
894
895 //
896 // Register so it will be automatically shadowed to memory
897 //
898 Status = PeiServicesRegisterForShadow (FileHandle);
899
900 //
901 // Make CpuIo pointer in PeiService table point to gCpuIoPpi
902 //
903 (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi;
904
905 if (Status == EFI_ALREADY_STARTED) {
906 //
907 // Shadow completed and running from memory
908 //
909 DEBUG ((EFI_D_INFO, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi));
910 } else {
911 Status = PeiServicesInstallPpi (&gPpiList);
912 ASSERT_EFI_ERROR (Status);
913 }
914
915 return EFI_SUCCESS;
916}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette