VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuIoPei/CpuIoPei.c

最後變更 在這個檔案是 99404,由 vboxsync 提交於 2 年 前

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

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

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