]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Mm.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for Mm shell Debug1 function.\r
3\r
c011b6c9 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
0027921b 5 Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
5d73d92f 7\r
8**/\r
9\r
10#include "UefiShellDebug1CommandsLib.h"\r
11#include <Library/ShellLib.h>\r
304316f4 12#include <Library/IoLib.h>\r
5d73d92f 13#include <Protocol/PciRootBridgeIo.h>\r
14#include <Protocol/DeviceIo.h>\r
15\r
16typedef enum {\r
304316f4
RN
17 ShellMmMemory,\r
18 ShellMmMemoryMappedIo,\r
19 ShellMmIo,\r
20 ShellMmPci,\r
21 ShellMmPciExpress\r
22} SHELL_MM_ACCESS_TYPE;\r
23\r
47d20b54 24CONST UINT16 mShellMmAccessTypeStr[] = {\r
304316f4
RN
25 STRING_TOKEN (STR_MM_MEM),\r
26 STRING_TOKEN (STR_MM_MMIO),\r
27 STRING_TOKEN (STR_MM_IO),\r
28 STRING_TOKEN (STR_MM_PCI),\r
29 STRING_TOKEN (STR_MM_PCIE)\r
30};\r
5d73d92f 31\r
47d20b54
MK
32STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
33 { L"-mmio", TypeFlag },\r
34 { L"-mem", TypeFlag },\r
35 { L"-io", TypeFlag },\r
36 { L"-pci", TypeFlag },\r
37 { L"-pcie", TypeFlag },\r
38 { L"-n", TypeFlag },\r
39 { L"-w", TypeValue },\r
40 { NULL, TypeMax }\r
41};\r
42\r
43CONST UINT64 mShellMmMaxNumber[] = {\r
304316f4
RN
44 0, MAX_UINT8, MAX_UINT16, 0, MAX_UINT32, 0, 0, 0, MAX_UINT64\r
45};\r
47d20b54 46CONST EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH mShellMmRootBridgeIoWidth[] = {\r
304316f4
RN
47 0, EfiPciWidthUint8, EfiPciWidthUint16, 0, EfiPciWidthUint32, 0, 0, 0, EfiPciWidthUint64\r
48};\r
47d20b54 49CONST EFI_CPU_IO_PROTOCOL_WIDTH mShellMmCpuIoWidth[] = {\r
304316f4
RN
50 0, EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 0, EfiCpuIoWidthUint32, 0, 0, 0, EfiCpuIoWidthUint64\r
51};\r
3737ac2b 52\r
53/**\r
304316f4 54 Extract the PCI segment, bus, device, function, register from\r
0027921b 55 from a PCI or PCIE format of address..\r
304316f4
RN
56\r
57 @param[in] PciFormat Whether the address is of PCI format of PCIE format.\r
0027921b 58 @param[in] Address PCI or PCIE address.\r
304316f4
RN
59 @param[out] Segment PCI segment number.\r
60 @param[out] Bus PCI bus number.\r
61 @param[out] Device PCI device number.\r
62 @param[out] Function PCI function number.\r
63 @param[out] Register PCI register offset.\r
3737ac2b 64**/\r
5d73d92f 65VOID\r
304316f4 66ShellMmDecodePciAddress (\r
47d20b54
MK
67 IN BOOLEAN PciFormat,\r
68 IN UINT64 Address,\r
69 OUT UINT32 *Segment,\r
70 OUT UINT8 *Bus,\r
71 OUT UINT8 *Device OPTIONAL,\r
72 OUT UINT8 *Function OPTIONAL,\r
73 OUT UINT32 *Register OPTIONAL\r
3737ac2b 74 )\r
75{\r
304316f4
RN
76 if (PciFormat) {\r
77 //\r
0027921b
RN
78 // PCI Configuration Space.The address will have the format ssssbbddffrr,\r
79 // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.\r
304316f4 80 //\r
47d20b54
MK
81 *Segment = (UINT32)(RShiftU64 (Address, 32) & 0xFFFF);\r
82 *Bus = (UINT8)(((UINT32)Address) >> 24);\r
304316f4
RN
83\r
84 if (Device != NULL) {\r
47d20b54 85 *Device = (UINT8)(((UINT32)Address) >> 16);\r
304316f4 86 }\r
47d20b54 87\r
304316f4 88 if (Function != NULL) {\r
47d20b54 89 *Function = (UINT8)(((UINT32)Address) >> 8);\r
3737ac2b 90 }\r
47d20b54 91\r
304316f4 92 if (Register != NULL) {\r
47d20b54 93 *Register = (UINT8)Address;\r
304316f4
RN
94 }\r
95 } else {\r
96 //\r
0027921b
RN
97 // PCI Express Configuration Space.The address will have the format ssssssbbddffrrr,\r
98 // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register.\r
304316f4 99 //\r
47d20b54
MK
100 *Segment = (UINT32)(RShiftU64 (Address, 36) & 0xFFFF);\r
101 *Bus = (UINT8)RShiftU64 (Address, 28);\r
304316f4 102 if (Device != NULL) {\r
47d20b54 103 *Device = (UINT8)(((UINT32)Address) >> 20);\r
304316f4 104 }\r
47d20b54 105\r
304316f4 106 if (Function != NULL) {\r
47d20b54 107 *Function = (UINT8)(((UINT32)Address) >> 12);\r
304316f4 108 }\r
47d20b54 109\r
304316f4 110 if (Register != NULL) {\r
47d20b54 111 *Register = (UINT32)(Address & 0xFFF);\r
304316f4
RN
112 }\r
113 }\r
3737ac2b 114}\r
115\r
116/**\r
304316f4
RN
117 Read or write some data from or into the Address.\r
118\r
119 @param[in] AccessType Access type.\r
120 @param[in] PciRootBridgeIo PciRootBridgeIo instance.\r
121 @param[in] CpuIo CpuIo instance.\r
122 @param[in] Read TRUE for read, FALSE for write.\r
123 @param[in] Addresss The memory location to access.\r
124 @param[in] Size The size of Buffer in Width sized units.\r
125 @param[in, out] Buffer The buffer to read into or write from.\r
3737ac2b 126**/\r
5d73d92f 127VOID\r
304316f4 128ShellMmAccess (\r
47d20b54
MK
129 IN SHELL_MM_ACCESS_TYPE AccessType,\r
130 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
131 IN EFI_CPU_IO2_PROTOCOL *CpuIo,\r
132 IN BOOLEAN Read,\r
133 IN UINT64 Address,\r
134 IN UINTN Size,\r
135 IN OUT VOID *Buffer\r
3737ac2b 136 )\r
137{\r
47d20b54
MK
138 EFI_STATUS Status;\r
139 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM RootBridgeIoMem;\r
140 EFI_CPU_IO_PROTOCOL_IO_MEM CpuIoMem;\r
141 UINT32 Segment;\r
142 UINT8 Bus;\r
143 UINT8 Device;\r
144 UINT8 Function;\r
145 UINT32 Register;\r
304316f4
RN
146\r
147 if (AccessType == ShellMmMemory) {\r
148 if (Read) {\r
47d20b54 149 CopyMem (Buffer, (VOID *)(UINTN)Address, Size);\r
3737ac2b 150 } else {\r
47d20b54 151 CopyMem ((VOID *)(UINTN)Address, Buffer, Size);\r
304316f4
RN
152 }\r
153 } else {\r
154 RootBridgeIoMem = NULL;\r
47d20b54 155 CpuIoMem = NULL;\r
304316f4 156 switch (AccessType) {\r
47d20b54
MK
157 case ShellMmPci:\r
158 case ShellMmPciExpress:\r
159 ASSERT (PciRootBridgeIo != NULL);\r
160 ShellMmDecodePciAddress ((BOOLEAN)(AccessType == ShellMmPci), Address, &Segment, &Bus, &Device, &Function, &Register);\r
161 if (Read) {\r
162 Status = PciRootBridgeIo->Pci.Read (\r
163 PciRootBridgeIo,\r
164 mShellMmRootBridgeIoWidth[Size],\r
165 EFI_PCI_ADDRESS (Bus, Device, Function, Register),\r
166 1,\r
167 Buffer\r
168 );\r
169 } else {\r
170 Status = PciRootBridgeIo->Pci.Write (\r
171 PciRootBridgeIo,\r
172 mShellMmRootBridgeIoWidth[Size],\r
173 EFI_PCI_ADDRESS (Bus, Device, Function, Register),\r
174 1,\r
175 Buffer\r
176 );\r
177 }\r
304316f4 178\r
47d20b54
MK
179 ASSERT_EFI_ERROR (Status);\r
180 return;\r
304316f4 181\r
47d20b54
MK
182 case ShellMmMemoryMappedIo:\r
183 if (PciRootBridgeIo != NULL) {\r
184 RootBridgeIoMem = Read ? PciRootBridgeIo->Mem.Read : PciRootBridgeIo->Mem.Write;\r
185 }\r
186\r
187 if (CpuIo != NULL) {\r
188 CpuIoMem = Read ? CpuIo->Mem.Read : CpuIo->Mem.Write;\r
189 }\r
190\r
191 break;\r
192\r
193 case ShellMmIo:\r
194 if (PciRootBridgeIo != NULL) {\r
195 RootBridgeIoMem = Read ? PciRootBridgeIo->Io.Read : PciRootBridgeIo->Io.Write;\r
196 }\r
197\r
198 if (CpuIo != NULL) {\r
199 CpuIoMem = Read ? CpuIo->Io.Read : CpuIo->Io.Write;\r
200 }\r
201\r
202 break;\r
203 default:\r
204 ASSERT (FALSE);\r
205 break;\r
3737ac2b 206 }\r
304316f4
RN
207\r
208 Status = EFI_UNSUPPORTED;\r
209 if (RootBridgeIoMem != NULL) {\r
210 Status = RootBridgeIoMem (PciRootBridgeIo, mShellMmRootBridgeIoWidth[Size], Address, 1, Buffer);\r
211 }\r
47d20b54 212\r
304316f4
RN
213 if (EFI_ERROR (Status) && (CpuIoMem != NULL)) {\r
214 Status = CpuIoMem (CpuIo, mShellMmCpuIoWidth[Size], Address, 1, Buffer);\r
215 }\r
216\r
217 if (EFI_ERROR (Status)) {\r
218 if (AccessType == ShellMmIo) {\r
219 switch (Size) {\r
47d20b54
MK
220 case 1:\r
221 if (Read) {\r
222 *(UINT8 *)Buffer = IoRead8 ((UINTN)Address);\r
223 } else {\r
224 IoWrite8 ((UINTN)Address, *(UINT8 *)Buffer);\r
225 }\r
226\r
227 break;\r
228 case 2:\r
229 if (Read) {\r
230 *(UINT16 *)Buffer = IoRead16 ((UINTN)Address);\r
231 } else {\r
232 IoWrite16 ((UINTN)Address, *(UINT16 *)Buffer);\r
233 }\r
234\r
235 break;\r
236 case 4:\r
237 if (Read) {\r
238 *(UINT32 *)Buffer = IoRead32 ((UINTN)Address);\r
239 } else {\r
240 IoWrite32 ((UINTN)Address, *(UINT32 *)Buffer);\r
241 }\r
242\r
243 break;\r
244 case 8:\r
245 if (Read) {\r
246 *(UINT64 *)Buffer = IoRead64 ((UINTN)Address);\r
247 } else {\r
248 IoWrite64 ((UINTN)Address, *(UINT64 *)Buffer);\r
249 }\r
250\r
251 break;\r
252 default:\r
253 ASSERT (FALSE);\r
254 break;\r
304316f4
RN
255 }\r
256 } else {\r
257 switch (Size) {\r
47d20b54
MK
258 case 1:\r
259 if (Read) {\r
260 *(UINT8 *)Buffer = MmioRead8 ((UINTN)Address);\r
261 } else {\r
262 MmioWrite8 ((UINTN)Address, *(UINT8 *)Buffer);\r
263 }\r
264\r
265 break;\r
266 case 2:\r
267 if (Read) {\r
268 *(UINT16 *)Buffer = MmioRead16 ((UINTN)Address);\r
269 } else {\r
270 MmioWrite16 ((UINTN)Address, *(UINT16 *)Buffer);\r
271 }\r
272\r
273 break;\r
274 case 4:\r
275 if (Read) {\r
276 *(UINT32 *)Buffer = MmioRead32 ((UINTN)Address);\r
277 } else {\r
278 MmioWrite32 ((UINTN)Address, *(UINT32 *)Buffer);\r
279 }\r
280\r
281 break;\r
282 case 8:\r
283 if (Read) {\r
284 *(UINT64 *)Buffer = MmioRead64 ((UINTN)Address);\r
285 } else {\r
286 MmioWrite64 ((UINTN)Address, *(UINT64 *)Buffer);\r
287 }\r
288\r
289 break;\r
290 default:\r
291 ASSERT (FALSE);\r
292 break;\r
304316f4
RN
293 }\r
294 }\r
295 }\r
296 }\r
3737ac2b 297}\r
5d73d92f 298\r
3737ac2b 299/**\r
304316f4
RN
300 Find the CpuIo instance and PciRootBridgeIo instance in the platform.\r
301 If there are multiple PciRootBridgeIo instances, the instance which manages\r
302 the Address is returned.\r
3737ac2b 303\r
304316f4
RN
304 @param[in] AccessType Access type.\r
305 @param[in] Address Address to access.\r
306 @param[out] CpuIo Return the CpuIo instance.\r
307 @param[out] PciRootBridgeIo Return the proper PciRootBridgeIo instance.\r
3737ac2b 308\r
304316f4
RN
309 @retval TRUE There are PciRootBridgeIo instances in the platform.\r
310 @retval FALSE There isn't PciRootBridgeIo instance in the platform.\r
3737ac2b 311**/\r
5d73d92f 312BOOLEAN\r
304316f4 313ShellMmLocateIoProtocol (\r
47d20b54
MK
314 IN SHELL_MM_ACCESS_TYPE AccessType,\r
315 IN UINT64 Address,\r
316 OUT EFI_CPU_IO2_PROTOCOL **CpuIo,\r
317 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **PciRootBridgeIo\r
3737ac2b 318 )\r
319{\r
47d20b54
MK
320 EFI_STATUS Status;\r
321 UINTN Index;\r
322 UINTN HandleCount;\r
323 EFI_HANDLE *HandleBuffer;\r
324 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Io;\r
325 UINT32 Segment;\r
326 UINT8 Bus;\r
327 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
328\r
329 Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)CpuIo);\r
304316f4
RN
330 if (EFI_ERROR (Status)) {\r
331 *CpuIo = NULL;\r
332 }\r
333\r
334 *PciRootBridgeIo = NULL;\r
02d34825 335 HandleBuffer = NULL;\r
47d20b54
MK
336 Status = gBS->LocateHandleBuffer (\r
337 ByProtocol,\r
338 &gEfiPciRootBridgeIoProtocolGuid,\r
339 NULL,\r
340 &HandleCount,\r
341 &HandleBuffer\r
342 );\r
02d34825 343 if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) {\r
304316f4
RN
344 return FALSE;\r
345 }\r
346\r
f87b742a
MK
347 Segment = 0;\r
348 Bus = 0;\r
304316f4 349 if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {\r
47d20b54 350 ShellMmDecodePciAddress ((BOOLEAN)(AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL);\r
304316f4 351 }\r
5d73d92f 352\r
3737ac2b 353 //\r
304316f4 354 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment & bus number\r
3737ac2b 355 //\r
304316f4
RN
356 for (Index = 0; (Index < HandleCount) && (*PciRootBridgeIo == NULL); Index++) {\r
357 Status = gBS->HandleProtocol (\r
358 HandleBuffer[Index],\r
359 &gEfiPciRootBridgeIoProtocolGuid,\r
47d20b54 360 (VOID *)&Io\r
304316f4
RN
361 );\r
362 if (EFI_ERROR (Status)) {\r
363 continue;\r
3737ac2b 364 }\r
365\r
304316f4
RN
366 if ((((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) && (Io->SegmentNumber == Segment)) ||\r
367 ((AccessType == ShellMmIo) || (AccessType == ShellMmMemoryMappedIo))\r
47d20b54
MK
368 )\r
369 {\r
370 Status = Io->Configuration (Io, (VOID **)&Descriptors);\r
304316f4
RN
371 if (!EFI_ERROR (Status)) {\r
372 while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
373 //\r
374 // Compare the segment and bus range for PCI/PCIE access\r
375 //\r
376 if ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) &&\r
377 ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) &&\r
378 ((Bus >= Descriptors->AddrRangeMin) && (Bus <= Descriptors->AddrRangeMax))\r
47d20b54
MK
379 )\r
380 {\r
304316f4
RN
381 *PciRootBridgeIo = Io;\r
382 break;\r
383\r
47d20b54
MK
384 //\r
385 // Compare the address range for MMIO/IO access\r
386 //\r
304316f4
RN
387 } else if ((((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) && (AccessType == ShellMmIo)) ||\r
388 ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) && (AccessType == ShellMmMemoryMappedIo))\r
389 ) && ((Address >= Descriptors->AddrRangeMin) && (Address <= Descriptors->AddrRangeMax))\r
47d20b54
MK
390 )\r
391 {\r
304316f4
RN
392 *PciRootBridgeIo = Io;\r
393 break;\r
394 }\r
47d20b54 395\r
304316f4
RN
396 Descriptors++;\r
397 }\r
398 }\r
3737ac2b 399 }\r
304316f4 400 }\r
47d20b54 401\r
304316f4
RN
402 if (HandleBuffer != NULL) {\r
403 FreePool (HandleBuffer);\r
3737ac2b 404 }\r
405\r
304316f4 406 return TRUE;\r
5d73d92f 407}\r
408\r
409/**\r
410 Function for 'mm' command.\r
411\r
412 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
413 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
414**/\r
415SHELL_STATUS\r
416EFIAPI\r
417ShellCommandRunMm (\r
418 IN EFI_HANDLE ImageHandle,\r
419 IN EFI_SYSTEM_TABLE *SystemTable\r
420 )\r
421{\r
47d20b54
MK
422 EFI_STATUS Status;\r
423 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
424 EFI_CPU_IO2_PROTOCOL *CpuIo;\r
425 UINT64 Address;\r
426 UINT64 Value;\r
427 SHELL_MM_ACCESS_TYPE AccessType;\r
428 UINT64 Buffer;\r
429 UINTN Index;\r
430 UINTN Size;\r
431 BOOLEAN Complete;\r
432 CHAR16 *InputStr;\r
433 BOOLEAN Interactive;\r
434 LIST_ENTRY *Package;\r
435 CHAR16 *ProblemParam;\r
436 SHELL_STATUS ShellStatus;\r
437 CONST CHAR16 *Temp;\r
438 BOOLEAN HasPciRootBridgeIo;\r
439\r
440 Value = 0;\r
441 Address = 0;\r
304316f4 442 ShellStatus = SHELL_SUCCESS;\r
47d20b54
MK
443 InputStr = NULL;\r
444 Size = 1;\r
445 AccessType = ShellMmMemory;\r
5d73d92f 446\r
447 //\r
448 // Parse arguments\r
449 //\r
5d73d92f 450 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
304316f4 451 if (EFI_ERROR (Status)) {\r
47d20b54 452 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
304316f4
RN
453 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mm", ProblemParam);\r
454 FreePool (ProblemParam);\r
5d73d92f 455 ShellStatus = SHELL_INVALID_PARAMETER;\r
456 goto Done;\r
457 } else {\r
304316f4 458 ASSERT (FALSE);\r
5d73d92f 459 }\r
460 } else {\r
304316f4
RN
461 if (ShellCommandLineGetCount (Package) < 2) {\r
462 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mm");\r
5d73d92f 463 ShellStatus = SHELL_INVALID_PARAMETER;\r
464 goto Done;\r
304316f4
RN
465 } else if (ShellCommandLineGetCount (Package) > 3) {\r
466 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
5d73d92f 467 ShellStatus = SHELL_INVALID_PARAMETER;\r
468 goto Done;\r
47d20b54 469 } else if (ShellCommandLineGetFlag (Package, L"-w") && (ShellCommandLineGetValue (Package, L"-w") == NULL)) {\r
304316f4 470 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"mm", L"-w");\r
3737ac2b 471 ShellStatus = SHELL_INVALID_PARAMETER;\r
472 goto Done;\r
5d73d92f 473 } else {\r
304316f4
RN
474 if (ShellCommandLineGetFlag (Package, L"-mmio")) {\r
475 AccessType = ShellMmMemoryMappedIo;\r
47d20b54
MK
476 if ( ShellCommandLineGetFlag (Package, L"-mem")\r
477 || ShellCommandLineGetFlag (Package, L"-io")\r
478 || ShellCommandLineGetFlag (Package, L"-pci")\r
479 || ShellCommandLineGetFlag (Package, L"-pcie")\r
480 )\r
481 {\r
304316f4 482 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
3737ac2b 483 ShellStatus = SHELL_INVALID_PARAMETER;\r
484 goto Done;\r
485 }\r
304316f4
RN
486 } else if (ShellCommandLineGetFlag (Package, L"-mem")) {\r
487 AccessType = ShellMmMemory;\r
47d20b54
MK
488 if ( ShellCommandLineGetFlag (Package, L"-io")\r
489 || ShellCommandLineGetFlag (Package, L"-pci")\r
490 || ShellCommandLineGetFlag (Package, L"-pcie")\r
491 )\r
492 {\r
304316f4 493 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
3737ac2b 494 ShellStatus = SHELL_INVALID_PARAMETER;\r
495 goto Done;\r
496 }\r
304316f4
RN
497 } else if (ShellCommandLineGetFlag (Package, L"-io")) {\r
498 AccessType = ShellMmIo;\r
47d20b54
MK
499 if ( ShellCommandLineGetFlag (Package, L"-pci")\r
500 || ShellCommandLineGetFlag (Package, L"-pcie")\r
501 )\r
502 {\r
304316f4 503 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
3737ac2b 504 ShellStatus = SHELL_INVALID_PARAMETER;\r
505 goto Done;\r
506 }\r
304316f4
RN
507 } else if (ShellCommandLineGetFlag (Package, L"-pci")) {\r
508 AccessType = ShellMmPci;\r
509 if (ShellCommandLineGetFlag (Package, L"-pcie")\r
47d20b54
MK
510 )\r
511 {\r
304316f4 512 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
3737ac2b 513 ShellStatus = SHELL_INVALID_PARAMETER;\r
514 goto Done;\r
515 }\r
304316f4
RN
516 } else if (ShellCommandLineGetFlag (Package, L"-pcie")) {\r
517 AccessType = ShellMmPciExpress;\r
5d73d92f 518 }\r
519 }\r
520\r
f79868cd
JC
521 //\r
522 // Non interactive for a script file or for the specific parameter\r
523 //\r
304316f4
RN
524 Interactive = TRUE;\r
525 if (gEfiShellProtocol->BatchIsActive () || ShellCommandLineGetFlag (Package, L"-n")) {\r
5d73d92f 526 Interactive = FALSE;\r
527 }\r
528\r
304316f4 529 Temp = ShellCommandLineGetValue (Package, L"-w");\r
5d73d92f 530 if (Temp != NULL) {\r
304316f4 531 Size = ShellStrToUintn (Temp);\r
5d73d92f 532 }\r
47d20b54 533\r
304316f4
RN
534 if ((Size != 1) && (Size != 2) && (Size != 4) && (Size != 8)) {\r
535 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"mm", Temp, L"-w");\r
3737ac2b 536 ShellStatus = SHELL_INVALID_PARAMETER;\r
537 goto Done;\r
5d73d92f 538 }\r
539\r
47d20b54 540 Temp = ShellCommandLineGetRawValue (Package, 1);\r
304316f4
RN
541 Status = ShellConvertStringToUint64 (Temp, &Address, TRUE, FALSE);\r
542 if (EFI_ERROR (Status)) {\r
543 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);\r
544 ShellStatus = SHELL_INVALID_PARAMETER;\r
545 goto Done;\r
5d73d92f 546 }\r
547\r
548 if ((Address & (Size - 1)) != 0) {\r
304316f4
RN
549 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, L"mm", Address);\r
550 ShellStatus = SHELL_INVALID_PARAMETER;\r
551 goto Done;\r
552 }\r
553\r
5d73d92f 554 //\r
304316f4 555 // locate IO protocol interface\r
5d73d92f 556 //\r
304316f4
RN
557 HasPciRootBridgeIo = ShellMmLocateIoProtocol (AccessType, Address, &CpuIo, &PciRootBridgeIo);\r
558 if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {\r
559 if (!HasPciRootBridgeIo) {\r
560 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"mm");\r
5d73d92f 561 ShellStatus = SHELL_NOT_FOUND;\r
562 goto Done;\r
563 }\r
47d20b54 564\r
304316f4
RN
565 if (PciRootBridgeIo == NULL) {\r
566 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address);\r
5d73d92f 567 ShellStatus = SHELL_INVALID_PARAMETER;\r
568 goto Done;\r
569 }\r
570 }\r
571\r
a0cd353d 572 //\r
304316f4 573 // Mode 1: Directly set a value\r
a0cd353d 574 //\r
304316f4
RN
575 Temp = ShellCommandLineGetRawValue (Package, 2);\r
576 if (Temp != NULL) {\r
577 Status = ShellConvertStringToUint64 (Temp, &Value, TRUE, FALSE);\r
578 if (EFI_ERROR (Status)) {\r
579 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);\r
580 ShellStatus = SHELL_INVALID_PARAMETER;\r
581 goto Done;\r
582 }\r
583\r
584 if (Value > mShellMmMaxNumber[Size]) {\r
585 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp);\r
586 ShellStatus = SHELL_INVALID_PARAMETER;\r
587 goto Done;\r
a0cd353d 588 }\r
589\r
304316f4 590 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Value);\r
a0cd353d 591 goto Done;\r
592 }\r
5d73d92f 593\r
5d73d92f 594 //\r
304316f4 595 // Mode 2: Directly show a value\r
5d73d92f 596 //\r
597 if (!Interactive) {\r
304316f4
RN
598 if (!gEfiShellProtocol->BatchIsActive ()) {\r
599 ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);\r
5d73d92f 600 }\r
47d20b54 601\r
304316f4 602 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);\r
5d73d92f 603\r
304316f4
RN
604 if (!gEfiShellProtocol->BatchIsActive ()) {\r
605 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
606 }\r
47d20b54 607\r
304316f4
RN
608 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);\r
609 ShellPrintEx (-1, -1, L"\r\n");\r
5d73d92f 610 goto Done;\r
611 }\r
304316f4 612\r
5d73d92f 613 //\r
304316f4 614 // Mode 3: Show or set values in interactive mode\r
5d73d92f 615 //\r
616 Complete = FALSE;\r
617 do {\r
304316f4
RN
618 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);\r
619 ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);\r
620 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);\r
621 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]);\r
622 ShellPrintEx (-1, -1, L" > ");\r
5d73d92f 623 //\r
624 // wait user input to modify\r
625 //\r
626 if (InputStr != NULL) {\r
304316f4 627 FreePool (InputStr);\r
3737ac2b 628 InputStr = NULL;\r
5d73d92f 629 }\r
47d20b54
MK
630\r
631 ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID **)&InputStr);\r
5d73d92f 632\r
304316f4 633 if (InputStr != NULL) {\r
5d73d92f 634 //\r
304316f4 635 // skip space characters\r
5d73d92f 636 //\r
47d20b54
MK
637 for (Index = 0; InputStr[Index] == ' '; Index++) {\r
638 }\r
304316f4 639\r
f87b742a
MK
640 if (InputStr[Index] != CHAR_NULL) {\r
641 if ((InputStr[Index] == '.') || (InputStr[Index] == 'q') || (InputStr[Index] == 'Q')) {\r
642 Complete = TRUE;\r
643 } else if (!EFI_ERROR (ShellConvertStringToUint64 (InputStr + Index, &Buffer, TRUE, TRUE)) &&\r
644 (Buffer <= mShellMmMaxNumber[Size])\r
47d20b54
MK
645 )\r
646 {\r
f87b742a
MK
647 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Buffer);\r
648 } else {\r
649 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle, L"mm");\r
650 continue;\r
651 }\r
5d73d92f 652 }\r
5d73d92f 653 }\r
654\r
655 Address += Size;\r
304316f4 656 ShellPrintEx (-1, -1, L"\r\n");\r
5d73d92f 657 } while (!Complete);\r
658 }\r
47d20b54 659\r
304316f4 660 ASSERT (ShellStatus == SHELL_SUCCESS);\r
5d73d92f 661\r
304316f4 662Done:\r
5d73d92f 663 if (InputStr != NULL) {\r
304316f4 664 FreePool (InputStr);\r
5d73d92f 665 }\r
47d20b54 666\r
5d73d92f 667 if (Package != NULL) {\r
668 ShellCommandLineFreeVarList (Package);\r
669 }\r
47d20b54 670\r
5d73d92f 671 return ShellStatus;\r
672}\r