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