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