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