]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
ShellPkg/Mm: Fix build warnings
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Mm.c
... / ...
CommitLineData
1/** @file\r
2 Main file for Mm shell Debug1 function.\r
3\r
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
5 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>\r
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
18#include <Library/IoLib.h>\r
19#include <Protocol/PciRootBridgeIo.h>\r
20#include <Protocol/DeviceIo.h>\r
21\r
22typedef enum {\r
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
37\r
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
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
58\r
59/**\r
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
70**/\r
71VOID\r
72EFIAPI\r
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
81 )\r
82{\r
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
96 }\r
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
117}\r
118\r
119/**\r
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
129**/\r
130VOID\r
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
139 )\r
140{\r
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
153 } else {\r
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
198 ASSERT (FALSE);\r
199 break;\r
200 }\r
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
282}\r
283\r
284/**\r
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
288\r
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
293\r
294 @retval TRUE There are PciRootBridgeIo instances in the platform.\r
295 @retval FALSE There isn't PciRootBridgeIo instance in the platform.\r
296**/\r
297BOOLEAN\r
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
303 )\r
304{\r
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
320 HandleBuffer = NULL;\r
321 Status = gBS->LocateHandleBuffer (\r
322 ByProtocol,\r
323 &gEfiPciRootBridgeIoProtocolGuid,\r
324 NULL,\r
325 &HandleCount,\r
326 &HandleBuffer\r
327 );\r
328 if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) {\r
329 return FALSE;\r
330 }\r
331\r
332 Segment = 0;\r
333 Bus = 0;\r
334 if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) {\r
335 ShellMmDecodePciAddress ((BOOLEAN) (AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL);\r
336 }\r
337\r
338 //\r
339 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment & bus number\r
340 //\r
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
349 }\r
350\r
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
380 }\r
381 }\r
382 if (HandleBuffer != NULL) {\r
383 FreePool (HandleBuffer);\r
384 }\r
385\r
386 return TRUE;\r
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
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
426\r
427 //\r
428 // Parse arguments\r
429 //\r
430 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
431 if (EFI_ERROR (Status)) {\r
432 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
433 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mm", ProblemParam);\r
434 FreePool (ProblemParam);\r
435 ShellStatus = SHELL_INVALID_PARAMETER;\r
436 goto Done;\r
437 } else {\r
438 ASSERT (FALSE);\r
439 }\r
440 } else {\r
441 if (ShellCommandLineGetCount (Package) < 2) {\r
442 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mm");\r
443 ShellStatus = SHELL_INVALID_PARAMETER;\r
444 goto Done;\r
445 } else if (ShellCommandLineGetCount (Package) > 3) {\r
446 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm");\r
447 ShellStatus = SHELL_INVALID_PARAMETER;\r
448 goto Done;\r
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
451 ShellStatus = SHELL_INVALID_PARAMETER;\r
452 goto Done;\r
453 } else {\r
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
462 ShellStatus = SHELL_INVALID_PARAMETER;\r
463 goto Done;\r
464 }\r
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
472 ShellStatus = SHELL_INVALID_PARAMETER;\r
473 goto Done;\r
474 }\r
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
481 ShellStatus = SHELL_INVALID_PARAMETER;\r
482 goto Done;\r
483 }\r
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
489 ShellStatus = SHELL_INVALID_PARAMETER;\r
490 goto Done;\r
491 }\r
492 } else if (ShellCommandLineGetFlag (Package, L"-pcie")) {\r
493 AccessType = ShellMmPciExpress;\r
494 }\r
495 }\r
496\r
497 //\r
498 // Non interactive for a script file or for the specific parameter\r
499 //\r
500 Interactive = TRUE;\r
501 if (gEfiShellProtocol->BatchIsActive () || ShellCommandLineGetFlag (Package, L"-n")) {\r
502 Interactive = FALSE;\r
503 }\r
504\r
505 Temp = ShellCommandLineGetValue (Package, L"-w");\r
506 if (Temp != NULL) {\r
507 Size = ShellStrToUintn (Temp);\r
508 }\r
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
511 ShellStatus = SHELL_INVALID_PARAMETER;\r
512 goto Done;\r
513 }\r
514\r
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
521 }\r
522\r
523 if ((Address & (Size - 1)) != 0) {\r
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
531 ShellStatus = SHELL_INVALID_PARAMETER;\r
532 goto Done;\r
533 }\r
534\r
535 //\r
536 // locate IO protocol interface\r
537 //\r
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
542 ShellStatus = SHELL_NOT_FOUND;\r
543 goto Done;\r
544 }\r
545 if (PciRootBridgeIo == NULL) {\r
546 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address);\r
547 ShellStatus = SHELL_INVALID_PARAMETER;\r
548 goto Done;\r
549 }\r
550 }\r
551\r
552 //\r
553 // Mode 1: Directly set a value\r
554 //\r
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
568 }\r
569\r
570 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Value);\r
571 goto Done;\r
572 }\r
573\r
574 //\r
575 // Mode 2: Directly show a value\r
576 //\r
577 if (!Interactive) {\r
578 if (!gEfiShellProtocol->BatchIsActive ()) {\r
579 ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle);\r
580 }\r
581 ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer);\r
582\r
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
588 goto Done;\r
589 }\r
590\r
591 //\r
592 // Mode 3: Show or set values in interactive mode\r
593 //\r
594 Complete = FALSE;\r
595 do {\r
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
598 break;\r
599 }\r
600\r
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
606 //\r
607 // wait user input to modify\r
608 //\r
609 if (InputStr != NULL) {\r
610 FreePool (InputStr);\r
611 InputStr = NULL;\r
612 }\r
613 ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID**) &InputStr);\r
614\r
615 if (InputStr != NULL) {\r
616 //\r
617 // skip space characters\r
618 //\r
619 for (Index = 0; InputStr[Index] == ' '; Index++);\r
620\r
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
632 }\r
633 }\r
634\r
635 Address += Size;\r
636 ShellPrintEx (-1, -1, L"\r\n");\r
637 } while (!Complete);\r
638 }\r
639 ASSERT (ShellStatus == SHELL_SUCCESS);\r
640\r
641Done:\r
642 if (InputStr != NULL) {\r
643 FreePool (InputStr);\r
644 }\r
645 if (Package != NULL) {\r
646 ShellCommandLineFreeVarList (Package);\r
647 }\r
648 return ShellStatus;\r
649}\r