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