EmbeddedPkg: import Lan91x Ethernet controller driver
[mirror_edk2.git] / EmbeddedPkg / Drivers / FdtPlatformDxe / ShellDumpFdt.c
CommitLineData
b0866ad3
OM
1/** @file\r
2\r
3 Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
4\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "FdtPlatform.h"\r
16\r
17#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))\r
18#define PALIGN(p, a) ((void *)(ALIGN ((unsigned long)(p), (a))))\r
19#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))\r
20\r
21STATIC\r
22UINTN\r
23IsPrintableString (\r
24 IN CONST VOID* data,\r
25 IN UINTN len\r
26 )\r
27{\r
28 CONST CHAR8 *s = data;\r
29 CONST CHAR8 *ss;\r
30\r
31 // Zero length is not\r
32 if (len == 0) {\r
33 return 0;\r
34 }\r
35\r
36 // Must terminate with zero\r
37 if (s[len - 1] != '\0') {\r
38 return 0;\r
39 }\r
40\r
41 ss = s;\r
42 while (*s/* && isprint (*s)*/) {\r
43 s++;\r
44 }\r
45\r
46 // Not zero, or not done yet\r
47 if (*s != '\0' || (s + 1 - ss) < len) {\r
48 return 0;\r
49 }\r
50\r
51 return 1;\r
52}\r
53\r
54STATIC\r
55VOID\r
56PrintData (\r
57 IN CONST CHAR8* data,\r
58 IN UINTN len\r
59 )\r
60{\r
61 UINTN i;\r
62 CONST CHAR8 *p = data;\r
63\r
64 // No data, don't print\r
65 if (len == 0)\r
66 return;\r
67\r
68 if (IsPrintableString (data, len)) {\r
69 Print (L" = \"%a\"", (const char *)data);\r
70 } else if ((len % 4) == 0) {\r
71 Print (L" = <");\r
72 for (i = 0; i < len; i += 4) {\r
73 Print (L"0x%08x%a", fdt32_to_cpu (GET_CELL (p)), i < (len - 4) ? " " : "");\r
74 }\r
75 Print (L">");\r
76 } else {\r
77 Print (L" = [");\r
78 for (i = 0; i < len; i++)\r
79 Print (L"%02x%a", *p++, i < len - 1 ? " " : "");\r
80 Print (L"]");\r
81 }\r
82}\r
83\r
84STATIC\r
85VOID\r
86DumpFdt (\r
87 IN VOID* FdtBlob\r
88 )\r
89{\r
90 struct fdt_header *bph;\r
91 UINT32 off_dt;\r
92 UINT32 off_str;\r
93 CONST CHAR8* p_struct;\r
94 CONST CHAR8* p_strings;\r
95 CONST CHAR8* p;\r
96 CONST CHAR8* s;\r
97 CONST CHAR8* t;\r
98 UINT32 tag;\r
99 UINTN sz;\r
100 UINTN depth;\r
101 UINTN shift;\r
102 UINT32 version;\r
103\r
104 {\r
105 // Can 'memreserve' be printed by below code?\r
106 INTN num = fdt_num_mem_rsv (FdtBlob);\r
107 INTN i, err;\r
108 UINT64 addr = 0, size = 0;\r
109\r
110 for (i = 0; i < num; i++) {\r
111 err = fdt_get_mem_rsv (FdtBlob, i, &addr, &size);\r
112 if (err) {\r
113 DEBUG ((EFI_D_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i));\r
114 }\r
115 else {\r
116 Print (L"/memreserve/ \t0x%lx \t0x%lx;\n", addr, size);\r
117 }\r
118 }\r
119 }\r
120\r
121 depth = 0;\r
122 shift = 4;\r
123\r
124 bph = FdtBlob;\r
125 off_dt = fdt32_to_cpu (bph->off_dt_struct);\r
126 off_str = fdt32_to_cpu (bph->off_dt_strings);\r
127 p_struct = (CONST CHAR8*)FdtBlob + off_dt;\r
128 p_strings = (CONST CHAR8*)FdtBlob + off_str;\r
129 version = fdt32_to_cpu (bph->version);\r
130\r
131 p = p_struct;\r
132 while ((tag = fdt32_to_cpu (GET_CELL (p))) != FDT_END) {\r
133 if (tag == FDT_BEGIN_NODE) {\r
134 s = p;\r
135 p = PALIGN (p + AsciiStrLen (s) + 1, 4);\r
136\r
137 if (*s == '\0')\r
138 s = "/";\r
139\r
140 Print (L"%*s%a {\n", depth * shift, L" ", s);\r
141\r
142 depth++;\r
143 continue;\r
144 }\r
145\r
146 if (tag == FDT_END_NODE) {\r
147 depth--;\r
148\r
149 Print (L"%*s};\n", depth * shift, L" ");\r
150 continue;\r
151 }\r
152\r
153 if (tag == FDT_NOP) {\r
154 Print (L"%*s// [NOP]\n", depth * shift, L" ");\r
155 continue;\r
156 }\r
157\r
158 if (tag != FDT_PROP) {\r
159 Print (L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);\r
160 break;\r
161 }\r
162 sz = fdt32_to_cpu (GET_CELL (p));\r
163 s = p_strings + fdt32_to_cpu (GET_CELL (p));\r
164 if (version < 16 && sz >= 8)\r
165 p = PALIGN (p, 8);\r
166 t = p;\r
167\r
168 p = PALIGN (p + sz, 4);\r
169\r
170 Print (L"%*s%a", depth * shift, L" ", s);\r
171 PrintData (t, sz);\r
172 Print (L";\n");\r
173 }\r
174}\r
175\r
176/**\r
177 This is the shell command "dumpfdt" handler function. This function handles\r
178 the command when it is invoked in the shell.\r
179\r
180 @param[in] This The instance of the\r
181 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
182 @param[in] SystemTable The pointer to the UEFI system table.\r
183 @param[in] ShellParameters The parameters associated with the command.\r
184 @param[in] Shell The instance of the shell protocol used in the\r
185 context of processing this command.\r
186\r
187 @return SHELL_SUCCESS The operation was successful.\r
188 @return SHELL_ABORTED Operation aborted due to internal error.\r
189 @return SHELL_NOT_FOUND Failed to locate the Device Tree into the EFI Configuration Table\r
190 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r
191\r
192**/\r
193SHELL_STATUS\r
194EFIAPI\r
195ShellDynCmdDumpFdtHandler (\r
196 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
197 IN EFI_SYSTEM_TABLE *SystemTable,\r
198 IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
199 IN EFI_SHELL_PROTOCOL *Shell\r
200 )\r
201{\r
202 SHELL_STATUS ShellStatus;\r
203 EFI_STATUS Status;\r
204 VOID *FdtBlob;\r
205\r
206 ShellStatus = SHELL_SUCCESS;\r
207\r
208 //\r
209 // Install the Shell and Shell Parameters Protocols on the driver\r
210 // image. This is necessary for the initialisation of the Shell\r
211 // Library to succeed in the next step.\r
212 //\r
213 Status = gBS->InstallMultipleProtocolInterfaces (\r
214 &gImageHandle,\r
215 &gEfiShellProtocolGuid, Shell,\r
216 &gEfiShellParametersProtocolGuid, ShellParameters,\r
217 NULL\r
218 );\r
219 if (EFI_ERROR (Status)) {\r
220 return SHELL_ABORTED;\r
221 }\r
222\r
223 //\r
224 // Initialise the Shell Library as we are going to use it.\r
225 // Assert that the return code is EFI_SUCCESS as it should.\r
226 // To anticipate any change is the codes returned by\r
227 // ShellInitialize(), leave in case of error.\r
228 //\r
229 Status = ShellInitialize ();\r
230 if (EFI_ERROR (Status)) {\r
231 ASSERT_EFI_ERROR (Status);\r
232 return SHELL_ABORTED;\r
233 }\r
234\r
235 Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);\r
236 if (EFI_ERROR (Status)) {\r
237 Print (L"ERROR: Did not find the Fdt Blob.\n");\r
238 return EfiCodeToShellCode (Status);\r
239 }\r
240\r
241 DumpFdt (FdtBlob);\r
242\r
243 gBS->UninstallMultipleProtocolInterfaces (\r
244 gImageHandle,\r
245 &gEfiShellProtocolGuid, Shell,\r
246 &gEfiShellParametersProtocolGuid, ShellParameters,\r
247 NULL\r
248 );\r
249\r
250 return ShellStatus;\r
251}\r
252\r
253/**\r
254 This is the shell command "dumpfdt" help handler function. This\r
255 function returns the formatted help for the "dumpfdt" command.\r
256 The format matchs that in Appendix B of the revision 2.1 of the\r
257 UEFI Shell Specification.\r
258\r
259 @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
260 @param[in] Language The pointer to the language string to use.\r
261\r
262 @return CHAR16* Pool allocated help string, must be freed by caller.\r
263**/\r
264CHAR16*\r
265EFIAPI\r
266ShellDynCmdDumpFdtGetHelp (\r
267 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
268 IN CONST CHAR8 *Language\r
269 )\r
270{\r
271 //\r
272 // This allocates memory. The caller has to free the allocated memory.\r
273 //\r
274 return HiiGetString (\r
275 mFdtPlatformDxeHiiHandle,\r
276 STRING_TOKEN (STR_GET_HELP_DUMPFDT),\r
277 Language\r
278 );\r
279}\r