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