2 Main file for Mm shell Debug1 function.
4 Copyright (c) 2005 - 2010, 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>
31 IN EFI_HANDLE ImageHandle
,
32 IN EFI_SYSTEM_TABLE
*SystemTable
38 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
47 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
60 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
71 STATIC CONST UINT64 MaxNum
[9] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffff };
74 Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr
75 where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION
76 and rrr is REGISTER (extension format for PCI-E).
78 @param[in] InputAddress PCI address format on input.
79 @param[out]PciEAddress PCI-E address extention format.
83 GetPciEAddressFromInputAddress (
84 IN UINT64 InputAddress
,
85 OUT UINT64
*PciEAddress
88 *PciEAddress
= RShiftU64(InputAddress
& ~(UINT64
) 0xFFF, 4);
89 *PciEAddress
+= LShiftU64((UINT16
) InputAddress
& 0x0FFF, 32);
93 Function for 'mm' command.
95 @param[in] ImageHandle Handle to the Image (NULL if Internal).
96 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
101 IN EFI_HANDLE ImageHandle
,
102 IN EFI_SYSTEM_TABLE
*SystemTable
106 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*IoDev
;
110 UINT32 SegmentNumber
;
111 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
;
112 EFI_ACCESS_TYPE AccessType
;
121 EFI_HANDLE
*HandleBuffer
;
125 CHAR16
*ProblemParam
;
126 SHELL_STATUS ShellStatus
;
135 ShellStatus
= SHELL_SUCCESS
;
141 Width
= EfiPciWidthUint8
;
143 AccessType
= EfiMemory
;
149 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
150 if (EFI_ERROR(Status
)) {
151 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
152 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, ProblemParam
);
153 FreePool(ProblemParam
);
154 ShellStatus
= SHELL_INVALID_PARAMETER
;
160 if (ShellCommandLineGetCount(Package
) < 1) {
161 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
162 ShellStatus
= SHELL_INVALID_PARAMETER
;
164 } else if (ShellCommandLineGetCount(Package
) > 3) {
165 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
);
166 ShellStatus
= SHELL_INVALID_PARAMETER
;
169 if (ShellCommandLineGetFlag(Package
, L
"-mmio")) {
170 AccessType
= EFIMemoryMappedIo
;
171 } else if (ShellCommandLineGetFlag(Package
, L
"-mem")) {
172 AccessType
= EfiMemory
;
173 } else if (ShellCommandLineGetFlag(Package
, L
"-io")) {
175 } else if (ShellCommandLineGetFlag(Package
, L
"-pci")) {
176 AccessType
= EfiPciConfig
;
177 } else if (ShellCommandLineGetFlag(Package
, L
"-pcie")) {
178 AccessType
= EfiPciEConfig
;
182 if (ShellCommandLineGetFlag (Package
, L
"-n")) {
186 Temp
= ShellCommandLineGetValue(Package
, L
"-w");
188 ItemValue
= StrDecimalToUintn (Temp
);
192 Width
= EfiPciWidthUint8
;
197 Width
= EfiPciWidthUint16
;
202 Width
= EfiPciWidthUint32
;
207 Width
= EfiPciWidthUint64
;
212 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"-w");
213 ShellStatus
= SHELL_INVALID_PARAMETER
;
218 Temp
= ShellCommandLineGetRawValue(Package
, 1);
220 Address
= StrHexToUint64(Temp
);
223 Temp
= ShellCommandLineGetRawValue(Package
, 2);
225 Value
= StrHexToUint64(Temp
);
229 ShellStatus
= SHELL_INVALID_PARAMETER
;
234 if (Value
> 0xFFFF) {
235 ShellStatus
= SHELL_INVALID_PARAMETER
;
240 if (Value
> 0xFFFFFFFF) {
241 ShellStatus
= SHELL_INVALID_PARAMETER
;
249 if (ShellStatus
!= SHELL_SUCCESS
) {
250 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Temp
);
251 ShellStatus
= SHELL_INVALID_PARAMETER
;
256 if ((Address
& (Size
- 1)) != 0) {
257 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_NOT_ALIGNED
), gShellDebug1HiiHandle
, Address
);
258 ShellStatus
= SHELL_INVALID_PARAMETER
;
262 // locate DeviceIO protocol interface
264 if (AccessType
!= EfiMemory
) {
265 Status
= gBS
->LocateHandleBuffer (
267 &gEfiPciRootBridgeIoProtocolGuid
,
272 if (EFI_ERROR (Status
)) {
273 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PCIRBIO_NF
), gShellDebug1HiiHandle
);
274 ShellStatus
= SHELL_NOT_FOUND
;
278 // In the case of PCI or PCIE
279 // Get segment number and mask the segment bits in Address
281 if (AccessType
== EfiPciEConfig
) {
282 SegmentNumber
= (UINT32
) RShiftU64 (Address
, 36) & 0xff;
283 Address
&= 0xfffffffff;
285 if (AccessType
== EfiPciConfig
) {
286 SegmentNumber
= (UINT32
) RShiftU64 (Address
, 32) & 0xff;
287 Address
&= 0xffffffff;
291 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
293 for (Index
= 0; Index
< BufferSize
; Index
++) {
294 Status
= gBS
->HandleProtocol (
296 &gEfiPciRootBridgeIoProtocolGuid
,
299 if (EFI_ERROR (Status
)) {
302 if (IoDev
->SegmentNumber
!= SegmentNumber
) {
308 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND
), gShellDebug1HiiHandle
, SegmentNumber
);
309 ShellStatus
= SHELL_INVALID_PARAMETER
;
314 if (AccessType
== EfiIo
&& Address
+ Size
> 0x10000) {
315 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS_RANGE
), gShellDebug1HiiHandle
);
316 ShellStatus
= SHELL_INVALID_PARAMETER
;
320 if (AccessType
== EfiPciEConfig
) {
321 GetPciEAddressFromInputAddress (Address
, &PciEAddress
);
327 // if (ValueStr != NULL) {
328 // if (AccessType == EFIMemoryMappedIo) {
329 // IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);
330 // } else if (AccessType == EfiIo) {
331 // IoDev->Io.Write (IoDev, Width, Address, 1, &Value);
332 // } else if (AccessType == EfiPciConfig) {
333 // IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);
334 // } else if (AccessType == EfiPciEConfig) {
335 // IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);
337 // WriteMem (Width, Address, 1, &Value);
340 // ASSERT(ShellStatus == SHELL_SUCCESS);
346 // non-interactive mode
350 if (AccessType
== EFIMemoryMappedIo
) {
351 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MMIO
), gShellDebug1HiiHandle
);
352 IoDev
->Mem
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
353 } else if (AccessType
== EfiIo
) {
354 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_IO
), gShellDebug1HiiHandle
);
355 IoDev
->Io
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
356 } else if (AccessType
== EfiPciConfig
) {
357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCI
), gShellDebug1HiiHandle
);
358 IoDev
->Pci
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
359 } else if (AccessType
== EfiPciEConfig
) {
360 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCIE
), gShellDebug1HiiHandle
);
361 IoDev
->Pci
.Read (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
363 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MEM
), gShellDebug1HiiHandle
);
364 ReadMem (Width
, Address
, 1, &Buffer
);
367 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
369 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF2
), gShellDebug1HiiHandle
, Buffer
);
370 } else if (Size
== 2) {
371 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF4
), gShellDebug1HiiHandle
, Buffer
);
372 } else if (Size
== 4) {
373 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF8
), gShellDebug1HiiHandle
, Buffer
);
374 } else if (Size
== 8) {
375 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF16
), gShellDebug1HiiHandle
, Buffer
);
378 ShellPrintEx(-1, -1, L
"\r\n");
380 ASSERT(ShellStatus
== SHELL_SUCCESS
);
388 if (AccessType
== EfiIo
&& Address
+ Size
> 0x10000) {
389 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS_RANGE2
), gShellDebug1HiiHandle
);
390 // PrintToken (STRING_TOKEN (STR_IOMOD_IO_ADDRESS_2), HiiHandle, L"mm");
395 if (AccessType
== EFIMemoryMappedIo
) {
396 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MMIO
), gShellDebug1HiiHandle
);
397 // PrintToken (STRING_TOKEN (STR_IOMOD_HMMIO), HiiHandle);
398 IoDev
->Mem
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
399 } else if (AccessType
== EfiIo
) {
400 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_IO
), gShellDebug1HiiHandle
);
401 // PrintToken (STRING_TOKEN (STR_IOMOD_HIO), HiiHandle);
402 IoDev
->Io
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
403 } else if (AccessType
== EfiPciConfig
) {
404 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCI
), gShellDebug1HiiHandle
);
405 // PrintToken (STRING_TOKEN (STR_IOMOD_HPCI), HiiHandle);
406 IoDev
->Pci
.Read (IoDev
, Width
, Address
, 1, &Buffer
);
407 } else if (AccessType
== EfiPciEConfig
) {
408 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_PCIE
), gShellDebug1HiiHandle
);
409 // PrintToken (STRING_TOKEN (STR_IOMOD_HPCIE), HiiHandle);
410 IoDev
->Pci
.Read (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
412 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_MEM
), gShellDebug1HiiHandle
);
413 // PrintToken (STRING_TOKEN (STR_IOMOD_HMEM), HiiHandle);
414 ReadMem (Width
, Address
, 1, &Buffer
);
417 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
418 // PrintToken (STRING_TOKEN (STR_IOMOD_ADDRESS), HiiHandle, Address);
421 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF2
), gShellDebug1HiiHandle
, Buffer
);
422 // PrintToken (STRING_TOKEN (STR_IOMOD_BUFFER_2), HiiHandle, Buffer);
423 } else if (Size
== 2) {
424 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF4
), gShellDebug1HiiHandle
, Buffer
);
425 // PrintToken (STRING_TOKEN (STR_IOMOD_BUFFER_4), HiiHandle, Buffer);
426 } else if (Size
== 4) {
427 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF8
), gShellDebug1HiiHandle
, Buffer
);
428 // PrintToken (STRING_TOKEN (STR_IOMOD_BUFFER_8), HiiHandle, Buffer);
429 } else if (Size
== 8) {
430 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF16
), gShellDebug1HiiHandle
, Buffer
);
431 // PrintToken (STRING_TOKEN (STR_IOMOD_BUFFER_16), HiiHandle, Buffer);
434 // wait user input to modify
436 if (InputStr
!= NULL
) {
439 ShellPromptForResponse(ShellPromptResponseTypeFreeform
, NULL
, (VOID
**)&InputStr
);
442 // skip space characters
444 for (Index
= 0; InputStr
[Index
] == ' '; Index
++);
447 // parse input string
449 if (InputStr
[Index
] == '.' || InputStr
[Index
] == 'q' || InputStr
[Index
] == 'Q') {
451 } else if (InputStr
[Index
] == CHAR_NULL
) {
453 // Continue to next address
455 } else if (GetHex (InputStr
+ Index
, &Buffer
) && Buffer
<= MaxNum
[Width
]) {
456 if (AccessType
== EFIMemoryMappedIo
) {
457 IoDev
->Mem
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
458 } else if (AccessType
== EfiIo
) {
459 IoDev
->Io
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
460 } else if (AccessType
== EfiPciConfig
) {
461 IoDev
->Pci
.Write (IoDev
, Width
, Address
, 1, &Buffer
);
462 } else if (AccessType
== EfiPciEConfig
) {
463 IoDev
->Pci
.Write (IoDev
, Width
, PciEAddress
, 1, &Buffer
);
465 WriteMem (Width
, Address
, 1, &Buffer
);
468 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_ERROR
), gShellDebug1HiiHandle
);
469 // PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
474 if (AccessType
== EfiPciEConfig
) {
475 GetPciEAddressFromInputAddress (Address
, &PciEAddress
);
477 ShellPrintEx(-1, -1, L
"\r\n");
481 ASSERT(ShellStatus
== SHELL_SUCCESS
);
484 if (InputStr
!= NULL
) {
487 if (HandleBuffer
!= NULL
) {
488 FreePool (HandleBuffer
);
490 if (Package
!= NULL
) {
491 ShellCommandLineFreeVarList (Package
);
500 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
507 if (Width
== EfiPciWidthUint8
) {
508 *(UINT8
*) Buffer
= *(UINT8
*) (UINTN
) Address
;
510 } else if (Width
== EfiPciWidthUint16
) {
511 *(UINT16
*) Buffer
= *(UINT16
*) (UINTN
) Address
;
513 } else if (Width
== EfiPciWidthUint32
) {
514 *(UINT32
*) Buffer
= *(UINT32
*) (UINTN
) Address
;
516 } else if (Width
== EfiPciWidthUint64
) {
517 *(UINT64
*) Buffer
= *(UINT64
*) (UINTN
) Address
;
520 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MM_READ_ERROR
), gShellDebug1HiiHandle
);
521 // PrintToken (STRING_TOKEN (STR_IOMOD_READ_MEM_ERROR), HiiHandle);
534 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
541 if (Width
== EfiPciWidthUint8
) {
542 *(UINT8
*) (UINTN
) Address
= *(UINT8
*) Buffer
;
544 } else if (Width
== EfiPciWidthUint16
) {
545 *(UINT16
*) (UINTN
) Address
= *(UINT16
*) Buffer
;
547 } else if (Width
== EfiPciWidthUint32
) {
548 *(UINT32
*) (UINTN
) Address
= *(UINT32
*) Buffer
;
550 } else if (Width
== EfiPciWidthUint64
) {
551 *(UINT64
*) (UINTN
) Address
= *(UINT64
*) Buffer
;
576 // convert hex digits
580 while (c
!= CHAR_NULL
) {
581 if (c
>= 'a' && c
<= 'f') {
589 if ((c
>= '0' && c
<= '9') || (c
>= 'A' && c
<= 'F')) {
590 u
= u
<< 4 | c
- (c
>= 'A' ? 'A' - 10 : '0');