UefiCpuPkg: Modify CpuIoPei to support new IoLib library
[mirror_edk2.git] / UefiCpuPkg / CpuIoPei / CpuIoPei.c
CommitLineData
e643315b 1/** @file\r
2 Produces the CPU I/O PPI.\r
3\r
3d78c020 4Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
ff5d3cc2
LD
5Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
6\r
01a1c0fc 7This program and the accompanying materials \r
e643315b 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
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
57 \r
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
106 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
107 and Count is not valid for this EFI system.\r
108 \r
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
151 \r
152 //\r
153 // Check to see if any address associated with this transfer exceeds the maximum \r
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
160 // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count \r
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
e643315b 163 // \r
311004b2 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
172 } else { \r
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
181 \r
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
199 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
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
273 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
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
347 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
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
441 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
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
520 \r
521 return EFI_SUCCESS;\r
522}\r
523\r
524/**\r
525 8-bit I/O read operations.\r
526\r
527 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
548 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
570 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
592 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
614 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
636 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
658 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
680 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
702 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
724 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
746 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
768 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
790 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
812 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
834 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
856 @param[in] PeiServices An indirect pointer to the PEI Services Table published \r
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
881 @param[in] PeiServices Pointer to PEI Services Table \r
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
899 \r
900 //\r
901 // Make CpuIo pointer in PeiService table point to gCpuIoPpi\r
902 //\r
903 (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi;\r
904 \r
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
914 \r
915 return EFI_SUCCESS;\r
916}\r