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