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