2 Main file for Mm shell Debug1 function.
4 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellDebug1CommandsLib.h"
16 #include <Library/ShellLib.h>
17 #include <Protocol/PciRootBridgeIo.h>
18 #include <Protocol/DeviceIo.h>
28 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
39 STATIC CONST UINT64 MaxNum
[9] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffULL
};
42 Read some data into a buffer from memory.
44 @param[in] Width The width of each read.
45 @param[in] Addresss The memory location to start reading at.
46 @param[in] Size The size of Buffer in Width sized units.
47 @param[out] Buffer The buffer to read into.
52 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
59 // This function is defective. This ASSERT prevents the defect from affecting anything.
63 if (Width
== EfiPciWidthUint8
) {
64 *(UINT8
*) Buffer
= *(UINT8
*) (UINTN
) Address
;
66 } else if (Width
== EfiPciWidthUint16
) {
67 *(UINT16
*) Buffer
= *(UINT16
*) (UINTN
) Address
;
69 } else if (Width
== EfiPciWidthUint32
) {
70 *(UINT32
*) Buffer
= *(UINT32
*) (UINTN
) Address
;
72 } else if (Width
== EfiPciWidthUint64
) {
73 *(UINT64
*) Buffer
= *(UINT64
*) (UINTN
) Address
;
76 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_READ_ERROR
), gShellDebug1HiiHandle
);
84 Write some data to memory.
86 @param[in] Width The width of each write.
87 @param[in] Addresss The memory location to start writing at.
88 @param[in] Size The size of Buffer in Width sized units.
89 @param[in] Buffer The buffer to write from.
94 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
101 // This function is defective. This ASSERT prevents the defect from affecting anything.
105 if (Width
== EfiPciWidthUint8
) {
106 *(UINT8
*) (UINTN
) Address
= *(UINT8
*) Buffer
;
108 } else if (Width
== EfiPciWidthUint16
) {
109 *(UINT16
*) (UINTN
) Address
= *(UINT16
*) Buffer
;
111 } else if (Width
== EfiPciWidthUint32
) {
112 *(UINT32
*) (UINTN
) Address
= *(UINT32
*) Buffer
;
114 } else if (Width
== EfiPciWidthUint64
) {
115 *(UINT64
*) (UINTN
) Address
= *(UINT64
*) Buffer
;
128 Convert a string to it's hex data.
130 @param[in] str The pointer to the string of hex data.
131 @param[out] data The pointer to the buffer to fill. Valid upon a TRUE return.
133 @retval TRUE The conversion was successful.
134 @retval FALSE The conversion failed.
149 // convert hex digits
153 while (TempChar
!= CHAR_NULL
) {
154 if (TempChar
>= 'a' && TempChar
<= 'f') {
155 TempChar
-= 'a' - 'A';
158 if (TempChar
== ' ') {
162 if ((TempChar
>= '0' && TempChar
<= '9') || (TempChar
>= 'A' && TempChar
<= 'F')) {
163 TempUint
= (TempUint
<< 4) | (TempChar
- (TempChar
>= 'A' ? 'A' - 10 : '0'));
178 Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr
179 where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION
180 and rrr is REGISTER (extension format for PCI-E).
182 @param[in] InputAddress PCI address format on input.
183 @param[out]PciEAddress PCI-E address extention format.
187 GetPciEAddressFromInputAddress (
188 IN UINT64 InputAddress
,
189 OUT UINT64
*PciEAddress
192 *PciEAddress
= RShiftU64(InputAddress
& ~(UINT64
) 0xFFF, 4);
193 *PciEAddress
+= LShiftU64((UINT16
) InputAddress
& 0x0FFF, 32);
197 Function for 'mm' command.
199 @param[in] ImageHandle Handle to the Image (NULL if Internal).
200 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
205 IN EFI_HANDLE ImageHandle
,
206 IN EFI_SYSTEM_TABLE
*SystemTable
210 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*IoDev
;
214 UINT32 SegmentNumber
;
215 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
;
216 EFI_ACCESS_TYPE AccessType
;
224 EFI_HANDLE
*HandleBuffer
;
228 CHAR16
*ProblemParam
;
229 SHELL_STATUS ShellStatus
;
239 ShellStatus
= SHELL_SUCCESS
;
245 Width
= EfiPciWidthUint8
;
247 AccessType
= EfiMemory
;
252 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
253 if (EFI_ERROR(Status
)) {
254 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
255 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, ProblemParam
);
256 FreePool(ProblemParam
);
257 ShellStatus
= SHELL_INVALID_PARAMETER
;
263 if (ShellCommandLineGetCount(Package
) < 2) {
264 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
265 ShellStatus
= SHELL_INVALID_PARAMETER
;
267 } else if (ShellCommandLineGetCount(Package
) > 3) {
268 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
269 ShellStatus
= SHELL_INVALID_PARAMETER
;
271 } else if (ShellCommandLineGetFlag(Package
, L
"-w") && ShellCommandLineGetValue(Package
, L
"-w") == NULL
) {
272 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"-w");
273 ShellStatus
= SHELL_INVALID_PARAMETER
;
276 if (ShellCommandLineGetFlag(Package
, L
"-mmio")) {
277 AccessType
= EFIMemoryMappedIo
;
278 if (ShellCommandLineGetFlag(Package
, L
"-mem")
279 ||ShellCommandLineGetFlag(Package
, L
"-io")
280 ||ShellCommandLineGetFlag(Package
, L
"-pci")
281 ||ShellCommandLineGetFlag(Package
, L
"-pcie")
283 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
284 ShellStatus
= SHELL_INVALID_PARAMETER
;
287 } else if (ShellCommandLineGetFlag(Package
, L
"-mem")) {
288 AccessType
= EfiMemory
;
289 if (ShellCommandLineGetFlag(Package
, L
"-io")
290 ||ShellCommandLineGetFlag(Package
, L
"-pci")
291 ||ShellCommandLineGetFlag(Package
, L
"-pcie")
293 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
294 ShellStatus
= SHELL_INVALID_PARAMETER
;
297 } else if (ShellCommandLineGetFlag(Package
, L
"-io")) {
299 if (ShellCommandLineGetFlag(Package
, L
"-pci")
300 ||ShellCommandLineGetFlag(Package
, L
"-pcie")
302 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
303 ShellStatus
= SHELL_INVALID_PARAMETER
;
306 } else if (ShellCommandLineGetFlag(Package
, L
"-pci")) {
307 AccessType
= EfiPciConfig
;
308 if (ShellCommandLineGetFlag(Package
, L
"-pcie")
310 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
311 ShellStatus
= SHELL_INVALID_PARAMETER
;
314 } else if (ShellCommandLineGetFlag(Package
, L
"-pcie")) {
315 AccessType
= EfiPciEConfig
;
320 // Non interactive for a script file or for the specific parameter
322 if (gEfiShellProtocol
->BatchIsActive() || ShellCommandLineGetFlag (Package
, L
"-n")) {
326 Temp
= ShellCommandLineGetValue(Package
, L
"-w");
328 ItemValue
= ShellStrToUintn (Temp
);
332 Width
= EfiPciWidthUint8
;
337 Width
= EfiPciWidthUint16
;
342 Width
= EfiPciWidthUint32
;
347 Width
= EfiPciWidthUint64
;
352 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"-w");
353 ShellStatus
= SHELL_INVALID_PARAMETER
;
358 Temp
= ShellCommandLineGetRawValue(Package
, 1);
359 if (!ShellIsHexOrDecimalNumber(Temp
, TRUE
, FALSE
) || EFI_ERROR(ShellConvertStringToUint64(Temp
, (UINT64
*)&Address
, TRUE
, FALSE
))) {
360 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Temp
);
361 ShellStatus
= SHELL_INVALID_PARAMETER
;
365 Temp
= ShellCommandLineGetRawValue(Package
, 2);
368 // Per spec if value is specified, then -n is assumed.
372 if (!ShellIsHexOrDecimalNumber(Temp
, TRUE
, FALSE
) || EFI_ERROR(ShellConvertStringToUint64(Temp
, &Value
, TRUE
, FALSE
))) {
373 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Temp
);
374 ShellStatus
= SHELL_INVALID_PARAMETER
;
380 ShellStatus
= SHELL_INVALID_PARAMETER
;
385 if (Value
> 0xFFFF) {
386 ShellStatus
= SHELL_INVALID_PARAMETER
;
391 if (Value
> 0xFFFFFFFF) {
392 ShellStatus
= SHELL_INVALID_PARAMETER
;
400 if (ShellStatus
!= SHELL_SUCCESS
) {
401 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Temp
);
402 ShellStatus
= SHELL_INVALID_PARAMETER
;
407 if ((Address
& (Size
- 1)) != 0) {
408 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_NOT_ALIGNED
), gShellDebug1HiiHandle
, Address
);
409 ShellStatus
= SHELL_INVALID_PARAMETER
;
413 // locate DeviceIO protocol interface
415 if (AccessType
!= EfiMemory
) {
416 Status
= gBS
->LocateHandleBuffer (
418 &gEfiPciRootBridgeIoProtocolGuid
,
423 if (EFI_ERROR (Status
)) {
424 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PCIRBIO_NF
), gShellDebug1HiiHandle
);
425 ShellStatus
= SHELL_NOT_FOUND
;
429 // In the case of PCI or PCIE
430 // Get segment number and mask the segment bits in Address
432 if (AccessType
== EfiPciEConfig
) {
433 SegmentNumber
= (UINT32
) RShiftU64 (Address
, 36) & 0xff;
434 Address
&= 0xfffffffffULL
;
436 if (AccessType
== EfiPciConfig
) {
437 SegmentNumber
= (UINT32
) RShiftU64 (Address
, 32) & 0xff;
438 Address
&= 0xffffffff;
442 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
444 for (Index
= 0; Index
< BufferSize
; Index
++) {
445 Status
= gBS
->HandleProtocol (
447 &gEfiPciRootBridgeIoProtocolGuid
,
450 if (EFI_ERROR (Status
)) {
453 if (IoDev
->SegmentNumber
!= SegmentNumber
) {
458 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND
), gShellDebug1HiiHandle
, SegmentNumber
);
459 ShellStatus
= SHELL_INVALID_PARAMETER
;
464 if (AccessType
== EfiIo
&& Address
+ Size
> 0x10000) {
465 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS_RANGE
), gShellDebug1HiiHandle
);
466 ShellStatus
= SHELL_INVALID_PARAMETER
;
470 if (AccessType
== EfiPciEConfig
) {
471 GetPciEAddressFromInputAddress (Address
, &PciEAddress
);
477 if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
478 if (AccessType
== EFIMemoryMappedIo
) {
479 IoDev
->Mem
.Write (IoDev
, Width
, Address
, 1, &Value
);
480 } else if (AccessType
== EfiIo
) {
481 IoDev
->Io
.Write (IoDev
, Width
, Address
, 1, &Value
);
482 } else if (AccessType
== EfiPciConfig
) {
483 IoDev
->Pci
.Write (IoDev
, Width
, Address
, 1, &Value
);
484 } else if (AccessType
== EfiPciEConfig
) {
485 IoDev
->Pci
.Write (IoDev
, Width
, PciEAddress
, 1, &Value
);
487 WriteMem (Width
, Address
, 1, &Value
);
490 ASSERT(ShellStatus
== SHELL_SUCCESS
);
496 // non-interactive mode
500 if (AccessType
== EFIMemoryMappedIo
) {
501 if (!gEfiShellProtocol
->BatchIsActive()) {
502 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MMIO
), gShellDebug1HiiHandle
);
504 IoDev
->Mem
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
505 } else if (AccessType
== EfiIo
) {
506 if (!gEfiShellProtocol
->BatchIsActive()) {
507 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_IO
), gShellDebug1HiiHandle
);
509 IoDev
->Io
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
510 } else if (AccessType
== EfiPciConfig
) {
511 if (!gEfiShellProtocol
->BatchIsActive()) {
512 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCI
), gShellDebug1HiiHandle
);
514 IoDev
->Pci
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
515 } else if (AccessType
== EfiPciEConfig
) {
516 if (!gEfiShellProtocol
->BatchIsActive()) {
517 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCIE
), gShellDebug1HiiHandle
);
519 IoDev
->Pci
.Read (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
521 if (!gEfiShellProtocol
->BatchIsActive()) {
522 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MEM
), gShellDebug1HiiHandle
);
524 ReadMem (Width
, Address
, 1, &Buffer
);
526 if (!gEfiShellProtocol
->BatchIsActive()) {
527 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
530 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF2
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
531 } else if (Size
== 2) {
532 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF4
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
533 } else if (Size
== 4) {
534 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF8
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
535 } else if (Size
== 8) {
536 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF16
), gShellDebug1HiiHandle
, Buffer
);
539 ShellPrintEx(-1, -1, L
"\r\n");
541 ASSERT(ShellStatus
== SHELL_SUCCESS
);
549 if (AccessType
== EfiIo
&& Address
+ Size
> 0x10000) {
550 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS_RANGE2
), gShellDebug1HiiHandle
);
555 if (AccessType
== EFIMemoryMappedIo
) {
556 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MMIO
), gShellDebug1HiiHandle
);
557 IoDev
->Mem
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
558 } else if (AccessType
== EfiIo
) {
559 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_IO
), gShellDebug1HiiHandle
);
560 IoDev
->Io
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
561 } else if (AccessType
== EfiPciConfig
) {
562 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCI
), gShellDebug1HiiHandle
);
563 IoDev
->Pci
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
564 } else if (AccessType
== EfiPciEConfig
) {
565 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCIE
), gShellDebug1HiiHandle
);
566 IoDev
->Pci
.Read (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
568 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MEM
), gShellDebug1HiiHandle
);
569 ReadMem (Width
, Address
, 1, &Buffer
);
572 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
575 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF2
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
576 } else if (Size
== 2) {
577 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF4
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
578 } else if (Size
== 4) {
579 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF8
), gShellDebug1HiiHandle
, (UINTN
)Buffer
);
580 } else if (Size
== 8) {
581 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF16
), gShellDebug1HiiHandle
, Buffer
);
583 ShellPrintEx(-1, -1, L
" > ");
585 // wait user input to modify
587 if (InputStr
!= NULL
) {
591 ShellPromptForResponse(ShellPromptResponseTypeFreeform
, NULL
, (VOID
**)&InputStr
);
594 // skip space characters
596 for (Index
= 0; InputStr
!= NULL
&& InputStr
[Index
] == ' '; Index
++);
599 // parse input string
601 if (InputStr
!= NULL
&& (InputStr
[Index
] == '.' || InputStr
[Index
] == 'q' || InputStr
[Index
] == 'Q')) {
603 } else if (InputStr
== NULL
|| InputStr
[Index
] == CHAR_NULL
) {
605 // Continue to next address
607 } else if (GetHex (InputStr
+ Index
, &Buffer
) && Buffer
<= MaxNum
[Width
]) {
608 if (AccessType
== EFIMemoryMappedIo
) {
609 IoDev
->Mem
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
610 } else if (AccessType
== EfiIo
) {
611 IoDev
->Io
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
612 } else if (AccessType
== EfiPciConfig
) {
613 IoDev
->Pci
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
614 } else if (AccessType
== EfiPciEConfig
) {
615 IoDev
->Pci
.Write (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
617 WriteMem (Width
, Address
, 1, &Buffer
);
620 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ERROR
), gShellDebug1HiiHandle
);
622 // PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
626 if (AccessType
== EfiPciEConfig
) {
627 GetPciEAddressFromInputAddress (Address
, &PciEAddress
);
629 ShellPrintEx(-1, -1, L
"\r\n");
633 ASSERT(ShellStatus
== SHELL_SUCCESS
);
636 if (InputStr
!= NULL
) {
639 if (HandleBuffer
!= NULL
) {
640 FreePool (HandleBuffer
);
642 if (Package
!= NULL
) {
643 ShellCommandLineFreeVarList (Package
);