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