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