]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuIoPei/CpuIoPei.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
053e878b 46EFI_PEI_PPI_DESCRIPTOR gPpiList = {\r
e643315b 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
053e878b 55UINT8 mInStride[] = {\r
e643315b 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
053e878b 73UINT8 mOutStride[] = {\r
e643315b 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
053e878b 134 if ((Width >= EfiPeiCpuIoWidthFifoUint8) && (Width <= EfiPeiCpuIoWidthFifoUint64)) {\r
e643315b 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
053e878b 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
053e878b 171\r
e643315b 172 if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {\r
173 return EFI_UNSUPPORTED;\r
174 }\r
175 }\r
7367cc6c 176\r
e643315b 177 return EFI_SUCCESS;\r
178}\r
179\r
180/**\r
181 Reads memory-mapped registers.\r
182\r
183 @param[in] PeiServices An indirect pointer to the PEI Services Table\r
184 published by the PEI Foundation.\r
185 @param[in] This Pointer to local data for the interface.\r
186 @param[in] Width The width of the access. Enumerated in bytes.\r
187 @param[in] Address The physical address of the access.\r
188 @param[in] Count The number of accesses to perform.\r
189 @param[out] Buffer A pointer to the buffer of data.\r
190\r
191 @retval EFI_SUCCESS The function completed successfully.\r
192 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.\r
193 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
7367cc6c 194 @retval EFI_UNSUPPORTED The address range specified by Address, Width,\r
e643315b 195 and Count is not valid for this EFI system.\r
196\r
197**/\r
198EFI_STATUS\r
199EFIAPI\r
200CpuMemoryServiceRead (\r
201 IN CONST EFI_PEI_SERVICES **PeiServices,\r
202 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
203 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,\r
204 IN UINT64 Address,\r
205 IN UINTN Count,\r
206 OUT VOID *Buffer\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210 UINT8 InStride;\r
211 UINT8 OutStride;\r
212 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;\r
213 BOOLEAN Aligned;\r
214 UINT8 *Uint8Buffer;\r
215\r
216 Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);\r
217 if (EFI_ERROR (Status)) {\r
218 return Status;\r
219 }\r
220\r
221 //\r
222 // Select loop based on the width of the transfer\r
223 //\r
053e878b
MK
224 InStride = mInStride[Width];\r
225 OutStride = mOutStride[Width];\r
226 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH)(Width & 0x03);\r
227 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);\r
e643315b 228 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
229 if (OperationWidth == EfiPeiCpuIoWidthUint8) {\r
230 *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
231 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {\r
232 if (Aligned) {\r
233 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
234 } else {\r
235 WriteUnaligned16 ((UINT16 *)Uint8Buffer, MmioRead16 ((UINTN)Address));\r
236 }\r
237 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {\r
238 if (Aligned) {\r
239 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
240 } else {\r
241 WriteUnaligned32 ((UINT32 *)Uint8Buffer, MmioRead32 ((UINTN)Address));\r
242 }\r
243 } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {\r
244 if (Aligned) {\r
245 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
246 } else {\r
247 WriteUnaligned64 ((UINT64 *)Uint8Buffer, MmioRead64 ((UINTN)Address));\r
248 }\r
249 }\r
250 }\r
053e878b 251\r
e643315b 252 return EFI_SUCCESS;\r
253}\r
254\r
255/**\r
256 Writes memory-mapped registers.\r
257\r
258 @param[in] PeiServices An indirect pointer to the PEI Services Table\r
259 published by the PEI Foundation.\r
260 @param[in] This Pointer to local data for the interface.\r
261 @param[in] Width The width of the access. Enumerated in bytes.\r
262 @param[in] Address The physical address of the access.\r
263 @param[in] Count The number of accesses to perform.\r
264 @param[in] Buffer A pointer to the buffer of data.\r
265\r
266 @retval EFI_SUCCESS The function completed successfully.\r
267 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.\r
268 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
7367cc6c 269 @retval EFI_UNSUPPORTED The address range specified by Address, Width,\r
e643315b 270 and Count is not valid for this EFI system.\r
271\r
272**/\r
273EFI_STATUS\r
274EFIAPI\r
275CpuMemoryServiceWrite (\r
276 IN CONST EFI_PEI_SERVICES **PeiServices,\r
277 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
278 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,\r
279 IN UINT64 Address,\r
280 IN UINTN Count,\r
281 IN VOID *Buffer\r
282 )\r
283{\r
284 EFI_STATUS Status;\r
285 UINT8 InStride;\r
286 UINT8 OutStride;\r
287 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;\r
288 BOOLEAN Aligned;\r
289 UINT8 *Uint8Buffer;\r
290\r
291 Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);\r
292 if (EFI_ERROR (Status)) {\r
293 return Status;\r
294 }\r
295\r
296 //\r
297 // Select loop based on the width of the transfer\r
298 //\r
053e878b
MK
299 InStride = mInStride[Width];\r
300 OutStride = mOutStride[Width];\r
301 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH)(Width & 0x03);\r
302 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);\r
e643315b 303 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
304 if (OperationWidth == EfiPeiCpuIoWidthUint8) {\r
305 MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
306 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {\r
307 if (Aligned) {\r
308 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
309 } else {\r
310 MmioWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));\r
311 }\r
312 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {\r
313 if (Aligned) {\r
314 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
315 } else {\r
316 MmioWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));\r
317 }\r
318 } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {\r
319 if (Aligned) {\r
320 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
321 } else {\r
322 MmioWrite64 ((UINTN)Address, ReadUnaligned64 ((UINT64 *)Uint8Buffer));\r
323 }\r
324 }\r
325 }\r
053e878b 326\r
e643315b 327 return EFI_SUCCESS;\r
328}\r
329\r
330/**\r
331 Reads I/O registers.\r
332\r
333 @param[in] PeiServices An indirect pointer to the PEI Services Table\r
334 published by the PEI Foundation.\r
335 @param[in] This Pointer to local data for the interface.\r
336 @param[in] Width The width of the access. Enumerated in bytes.\r
337 @param[in] Address The physical address of the access.\r
338 @param[in] Count The number of accesses to perform.\r
339 @param[out] Buffer A pointer to the buffer of data.\r
340\r
341 @retval EFI_SUCCESS The function completed successfully.\r
342 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.\r
343 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
7367cc6c 344 @retval EFI_UNSUPPORTED The address range specified by Address, Width,\r
e643315b 345 and Count is not valid for this EFI system.\r
346\r
347**/\r
348EFI_STATUS\r
349EFIAPI\r
350CpuIoServiceRead (\r
351 IN CONST EFI_PEI_SERVICES **PeiServices,\r
352 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
353 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,\r
354 IN UINT64 Address,\r
355 IN UINTN Count,\r
356 OUT VOID *Buffer\r
357 )\r
358{\r
359 EFI_STATUS Status;\r
360 UINT8 InStride;\r
361 UINT8 OutStride;\r
362 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;\r
363 BOOLEAN Aligned;\r
364 UINT8 *Uint8Buffer;\r
365\r
366 Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);\r
367 if (EFI_ERROR (Status)) {\r
368 return Status;\r
369 }\r
370\r
371 //\r
372 // Select loop based on the width of the transfer\r
373 //\r
053e878b
MK
374 InStride = mInStride[Width];\r
375 OutStride = mOutStride[Width];\r
376 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH)(Width & 0x03);\r
ff5d3cc2
LD
377\r
378 //\r
379 // Fifo operations supported for (mInStride[Width] == 0)\r
380 //\r
381 if (InStride == 0) {\r
382 switch (OperationWidth) {\r
053e878b
MK
383 case EfiPeiCpuIoWidthUint8:\r
384 IoReadFifo8 ((UINTN)Address, Count, Buffer);\r
385 return EFI_SUCCESS;\r
386 case EfiPeiCpuIoWidthUint16:\r
387 IoReadFifo16 ((UINTN)Address, Count, Buffer);\r
388 return EFI_SUCCESS;\r
389 case EfiPeiCpuIoWidthUint32:\r
390 IoReadFifo32 ((UINTN)Address, Count, Buffer);\r
391 return EFI_SUCCESS;\r
392 default:\r
393 //\r
394 // The CpuIoCheckParameter call above will ensure that this\r
395 // path is not taken.\r
396 //\r
397 ASSERT (FALSE);\r
398 break;\r
ff5d3cc2
LD
399 }\r
400 }\r
401\r
e643315b 402 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);\r
403 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
404 if (OperationWidth == EfiPeiCpuIoWidthUint8) {\r
405 *Uint8Buffer = IoRead8 ((UINTN)Address);\r
406 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {\r
407 if (Aligned) {\r
408 *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);\r
409 } else {\r
410 WriteUnaligned16 ((UINT16 *)Uint8Buffer, IoRead16 ((UINTN)Address));\r
411 }\r
412 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {\r
413 if (Aligned) {\r
414 *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);\r
415 } else {\r
416 WriteUnaligned32 ((UINT32 *)Uint8Buffer, IoRead32 ((UINTN)Address));\r
417 }\r
418 }\r
419 }\r
420\r
421 return EFI_SUCCESS;\r
422}\r
423\r
424/**\r
425 Write I/O registers.\r
426\r
427 @param[in] PeiServices An indirect pointer to the PEI Services Table\r
428 published by the PEI Foundation.\r
429 @param[in] This Pointer to local data for the interface.\r
430 @param[in] Width The width of the access. Enumerated in bytes.\r
431 @param[in] Address The physical address of the access.\r
432 @param[in] Count The number of accesses to perform.\r
433 @param[in] Buffer A pointer to the buffer of data.\r
434\r
435 @retval EFI_SUCCESS The function completed successfully.\r
436 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.\r
437 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
7367cc6c 438 @retval EFI_UNSUPPORTED The address range specified by Address, Width,\r
e643315b 439 and Count is not valid for this EFI system.\r
440\r
441**/\r
442EFI_STATUS\r
443EFIAPI\r
444CpuIoServiceWrite (\r
445 IN CONST EFI_PEI_SERVICES **PeiServices,\r
446 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
447 IN EFI_PEI_CPU_IO_PPI_WIDTH Width,\r
448 IN UINT64 Address,\r
449 IN UINTN Count,\r
450 IN VOID *Buffer\r
451 )\r
452{\r
453 EFI_STATUS Status;\r
454 UINT8 InStride;\r
455 UINT8 OutStride;\r
456 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;\r
457 BOOLEAN Aligned;\r
458 UINT8 *Uint8Buffer;\r
459\r
460 //\r
461 // Make sure the parameters are valid\r
462 //\r
463 Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);\r
464 if (EFI_ERROR (Status)) {\r
465 return Status;\r
466 }\r
467\r
468 //\r
469 // Select loop based on the width of the transfer\r
470 //\r
053e878b
MK
471 InStride = mInStride[Width];\r
472 OutStride = mOutStride[Width];\r
473 OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH)(Width & 0x03);\r
ff5d3cc2
LD
474\r
475 //\r
476 // Fifo operations supported for (mInStride[Width] == 0)\r
477 //\r
478 if (InStride == 0) {\r
479 switch (OperationWidth) {\r
053e878b
MK
480 case EfiPeiCpuIoWidthUint8:\r
481 IoWriteFifo8 ((UINTN)Address, Count, Buffer);\r
482 return EFI_SUCCESS;\r
483 case EfiPeiCpuIoWidthUint16:\r
484 IoWriteFifo16 ((UINTN)Address, Count, Buffer);\r
485 return EFI_SUCCESS;\r
486 case EfiPeiCpuIoWidthUint32:\r
487 IoWriteFifo32 ((UINTN)Address, Count, Buffer);\r
488 return EFI_SUCCESS;\r
489 default:\r
490 //\r
491 // The CpuIoCheckParameter call above will ensure that this\r
492 // path is not taken.\r
493 //\r
494 ASSERT (FALSE);\r
495 break;\r
ff5d3cc2
LD
496 }\r
497 }\r
498\r
e643315b 499 Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);\r
500 for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
501 if (OperationWidth == EfiPeiCpuIoWidthUint8) {\r
502 IoWrite8 ((UINTN)Address, *Uint8Buffer);\r
503 } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {\r
504 if (Aligned) {\r
505 IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
506 } else {\r
507 IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));\r
508 }\r
509 } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {\r
510 if (Aligned) {\r
511 IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
512 } else {\r
513 IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));\r
514 }\r
515 }\r
516 }\r
7367cc6c 517\r
e643315b 518 return EFI_SUCCESS;\r
519}\r
520\r
521/**\r
522 8-bit I/O read operations.\r
523\r
7367cc6c 524 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 525 by the PEI Foundation.\r
526 @param[in] This Pointer to local data for the interface.\r
527 @param[in] Address The physical address of the access.\r
528\r
529 @return An 8-bit value returned from the I/O space.\r
530**/\r
531UINT8\r
532EFIAPI\r
533CpuIoRead8 (\r
534 IN CONST EFI_PEI_SERVICES **PeiServices,\r
535 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
536 IN UINT64 Address\r
537 )\r
538{\r
539 return IoRead8 ((UINTN)Address);\r
540}\r
541\r
542/**\r
543 16-bit I/O read operations.\r
544\r
7367cc6c 545 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 546 by the PEI Foundation.\r
547 @param[in] This Pointer to local data for the interface.\r
548 @param[in] Address The physical address of the access.\r
549\r
550 @return A 16-bit value returned from the I/O space.\r
551\r
552**/\r
553UINT16\r
554EFIAPI\r
555CpuIoRead16 (\r
556 IN CONST EFI_PEI_SERVICES **PeiServices,\r
557 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
558 IN UINT64 Address\r
559 )\r
560{\r
561 return IoRead16 ((UINTN)Address);\r
562}\r
563\r
564/**\r
565 32-bit I/O read operations.\r
566\r
7367cc6c 567 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 568 by the PEI Foundation.\r
569 @param[in] This Pointer to local data for the interface.\r
570 @param[in] Address The physical address of the access.\r
571\r
572 @return A 32-bit value returned from the I/O space.\r
573\r
574**/\r
575UINT32\r
576EFIAPI\r
577CpuIoRead32 (\r
053e878b
MK
578 IN CONST EFI_PEI_SERVICES **PeiServices,\r
579 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
580 IN UINT64 Address\r
e643315b 581 )\r
582{\r
583 return IoRead32 ((UINTN)Address);\r
584}\r
585\r
586/**\r
587 64-bit I/O read operations.\r
588\r
7367cc6c 589 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 590 by the PEI Foundation.\r
591 @param[in] This Pointer to local data for the interface.\r
592 @param[in] Address The physical address of the access.\r
593\r
594 @return A 64-bit value returned from the I/O space.\r
595\r
596**/\r
597UINT64\r
598EFIAPI\r
599CpuIoRead64 (\r
600 IN CONST EFI_PEI_SERVICES **PeiServices,\r
601 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
602 IN UINT64 Address\r
603 )\r
604{\r
605 return IoRead64 ((UINTN)Address);\r
606}\r
607\r
608/**\r
609 8-bit I/O write operations.\r
610\r
7367cc6c 611 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 612 by the PEI Foundation.\r
613 @param[in] This Pointer to local data for the interface.\r
614 @param[in] Address The physical address of the access.\r
615 @param[in] Data The data to write.\r
616\r
617**/\r
618VOID\r
619EFIAPI\r
620CpuIoWrite8 (\r
621 IN CONST EFI_PEI_SERVICES **PeiServices,\r
622 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
623 IN UINT64 Address,\r
624 IN UINT8 Data\r
625 )\r
626{\r
627 IoWrite8 ((UINTN)Address, Data);\r
628}\r
629\r
630/**\r
631 16-bit I/O write operations.\r
632\r
7367cc6c 633 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 634 by the PEI Foundation.\r
635 @param[in] This Pointer to local data for the interface.\r
636 @param[in] Address The physical address of the access.\r
637 @param[in] Data The data to write.\r
638\r
639**/\r
640VOID\r
641EFIAPI\r
642CpuIoWrite16 (\r
643 IN CONST EFI_PEI_SERVICES **PeiServices,\r
644 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
645 IN UINT64 Address,\r
646 IN UINT16 Data\r
647 )\r
648{\r
649 IoWrite16 ((UINTN)Address, Data);\r
650}\r
651\r
652/**\r
653 32-bit I/O write operations.\r
654\r
7367cc6c 655 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 656 by the PEI Foundation.\r
657 @param[in] This Pointer to local data for the interface.\r
658 @param[in] Address The physical address of the access.\r
659 @param[in] Data The data to write.\r
660\r
661**/\r
662VOID\r
663EFIAPI\r
664CpuIoWrite32 (\r
665 IN CONST EFI_PEI_SERVICES **PeiServices,\r
666 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
667 IN UINT64 Address,\r
668 IN UINT32 Data\r
669 )\r
670{\r
671 IoWrite32 ((UINTN)Address, Data);\r
672}\r
673\r
674/**\r
675 64-bit I/O write operations.\r
676\r
7367cc6c 677 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 678 by the PEI Foundation.\r
679 @param[in] This Pointer to local data for the interface.\r
680 @param[in] Address The physical address of the access.\r
681 @param[in] Data The data to write.\r
682\r
683**/\r
684VOID\r
685EFIAPI\r
686CpuIoWrite64 (\r
687 IN CONST EFI_PEI_SERVICES **PeiServices,\r
688 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
689 IN UINT64 Address,\r
690 IN UINT64 Data\r
691 )\r
692{\r
693 IoWrite64 ((UINTN)Address, Data);\r
694}\r
695\r
696/**\r
697 8-bit memory read operations.\r
698\r
7367cc6c 699 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 700 by the PEI Foundation.\r
701 @param[in] This Pointer to local data for the interface.\r
702 @param[in] Address The physical address of the access.\r
703\r
704 @return An 8-bit value returned from the memory space.\r
705\r
706**/\r
707UINT8\r
708EFIAPI\r
709CpuMemRead8 (\r
710 IN CONST EFI_PEI_SERVICES **PeiServices,\r
711 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
712 IN UINT64 Address\r
713 )\r
714{\r
715 return MmioRead8 ((UINTN)Address);\r
716}\r
717\r
718/**\r
719 16-bit memory read operations.\r
720\r
7367cc6c 721 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 722 by the PEI Foundation.\r
723 @param[in] This Pointer to local data for the interface.\r
724 @param[in] Address The physical address of the access.\r
725\r
726 @return A 16-bit value returned from the memory space.\r
727\r
728**/\r
729UINT16\r
730EFIAPI\r
731CpuMemRead16 (\r
732 IN CONST EFI_PEI_SERVICES **PeiServices,\r
733 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
734 IN UINT64 Address\r
735 )\r
736{\r
737 return MmioRead16 ((UINTN)Address);\r
738}\r
739\r
740/**\r
741 32-bit memory read operations.\r
742\r
7367cc6c 743 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 744 by the PEI Foundation.\r
745 @param[in] This Pointer to local data for the interface.\r
746 @param[in] Address The physical address of the access.\r
747\r
748 @return A 32-bit value returned from the memory space.\r
749\r
750**/\r
751UINT32\r
752EFIAPI\r
753CpuMemRead32 (\r
754 IN CONST EFI_PEI_SERVICES **PeiServices,\r
755 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
756 IN UINT64 Address\r
757 )\r
758{\r
759 return MmioRead32 ((UINTN)Address);\r
760}\r
761\r
762/**\r
763 64-bit memory read operations.\r
764\r
7367cc6c 765 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 766 by the PEI Foundation.\r
767 @param[in] This Pointer to local data for the interface.\r
768 @param[in] Address The physical address of the access.\r
769\r
770 @return A 64-bit value returned from the memory space.\r
771\r
772**/\r
773UINT64\r
774EFIAPI\r
775CpuMemRead64 (\r
776 IN CONST EFI_PEI_SERVICES **PeiServices,\r
777 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
778 IN UINT64 Address\r
779 )\r
780{\r
781 return MmioRead64 ((UINTN)Address);\r
782}\r
783\r
784/**\r
785 8-bit memory write operations.\r
786\r
7367cc6c 787 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 788 by the PEI Foundation.\r
789 @param[in] This Pointer to local data for the interface.\r
790 @param[in] Address The physical address of the access.\r
791 @param[in] Data The data to write.\r
792\r
793**/\r
794VOID\r
795EFIAPI\r
796CpuMemWrite8 (\r
797 IN CONST EFI_PEI_SERVICES **PeiServices,\r
798 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
799 IN UINT64 Address,\r
800 IN UINT8 Data\r
801 )\r
802{\r
803 MmioWrite8 ((UINTN)Address, Data);\r
804}\r
805\r
806/**\r
807 16-bit memory write operations.\r
808\r
7367cc6c 809 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 810 by the PEI Foundation.\r
811 @param[in] This Pointer to local data for the interface.\r
812 @param[in] Address The physical address of the access.\r
813 @param[in] Data The data to write.\r
814\r
815**/\r
816VOID\r
817EFIAPI\r
818CpuMemWrite16 (\r
819 IN CONST EFI_PEI_SERVICES **PeiServices,\r
820 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
821 IN UINT64 Address,\r
822 IN UINT16 Data\r
823 )\r
824{\r
825 MmioWrite16 ((UINTN)Address, Data);\r
826}\r
827\r
828/**\r
829 32-bit memory write operations.\r
830\r
7367cc6c 831 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 832 by the PEI Foundation.\r
833 @param[in] This Pointer to local data for the interface.\r
834 @param[in] Address The physical address of the access.\r
835 @param[in] Data The data to write.\r
836\r
837**/\r
838VOID\r
839EFIAPI\r
840CpuMemWrite32 (\r
841 IN CONST EFI_PEI_SERVICES **PeiServices,\r
842 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
843 IN UINT64 Address,\r
844 IN UINT32 Data\r
845 )\r
846{\r
847 MmioWrite32 ((UINTN)Address, Data);\r
848}\r
849\r
850/**\r
851 64-bit memory write operations.\r
852\r
7367cc6c 853 @param[in] PeiServices An indirect pointer to the PEI Services Table published\r
e643315b 854 by the PEI Foundation.\r
855 @param[in] This Pointer to local data for the interface.\r
856 @param[in] Address The physical address of the access.\r
857 @param[in] Data The data to write.\r
858\r
859**/\r
860VOID\r
861EFIAPI\r
862CpuMemWrite64 (\r
863 IN CONST EFI_PEI_SERVICES **PeiServices,\r
864 IN CONST EFI_PEI_CPU_IO_PPI *This,\r
865 IN UINT64 Address,\r
866 IN UINT64 Data\r
867 )\r
868{\r
869 MmioWrite64 ((UINTN)Address, Data);\r
870}\r
871\r
872/**\r
873 The Entry point of the CPU I/O PEIM\r
874\r
875 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.\r
876\r
877 @param[in] FileHandle Pointer to image file handle.\r
7367cc6c 878 @param[in] PeiServices Pointer to PEI Services Table\r
e643315b 879\r
880 @retval EFI_SUCCESS CPU I/O PPI successfully installed\r
881\r
882**/\r
883EFI_STATUS\r
884EFIAPI\r
885CpuIoInitialize (\r
886 IN EFI_PEI_FILE_HANDLE FileHandle,\r
887 IN CONST EFI_PEI_SERVICES **PeiServices\r
888 )\r
889{\r
890 EFI_STATUS Status;\r
891\r
892 //\r
893 // Register so it will be automatically shadowed to memory\r
894 //\r
895 Status = PeiServicesRegisterForShadow (FileHandle);\r
7367cc6c 896\r
e643315b 897 //\r
898 // Make CpuIo pointer in PeiService table point to gCpuIoPpi\r
899 //\r
900 (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi;\r
7367cc6c 901\r
e643315b 902 if (Status == EFI_ALREADY_STARTED) {\r
903 //\r
904 // Shadow completed and running from memory\r
905 //\r
96e1cba5 906 DEBUG ((DEBUG_INFO, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi));\r
e643315b 907 } else {\r
908 Status = PeiServicesInstallPpi (&gPpiList);\r
909 ASSERT_EFI_ERROR (Status);\r
910 }\r
7367cc6c 911\r
e643315b 912 return EFI_SUCCESS;\r
913}\r