]>
Commit | Line | Data |
---|---|---|
48837c22 | 1 | From 82540f3a4b280133f2d1a58cb8baba01c1f09690 Mon Sep 17 00:00:00 2001 |
2 | From: Olivier Martin <olivier.martin@arm.com> | |
3 | Date: Thu, 16 Feb 2012 15:56:40 +0000 | |
4 | Subject: [PATCH 3/3] ArmPlatformPkg/EblCmdLib: Add 'dumpfdt' EBL command | |
5 | ||
6 | This command dumps the FDT blob pointed by the Device Path defined in the | |
7 | command argument or used the Platform specifc FDT defined by its Device Path | |
8 | in the UEFI Variable 'Fdt' or the PcdFdtDevicePath PCD. | |
9 | --- | |
10 | ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | 206 ++++++++++++++++++++++++ | |
11 | ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | 12 ++ | |
12 | ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | 6 + | |
13 | 3 files changed, 224 insertions(+), 0 deletions(-) | |
14 | create mode 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | |
15 | mode change 100644 => 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | |
16 | mode change 100644 => 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | |
17 | ||
18 | diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | |
19 | new file mode 100755 | |
20 | index 0000000..3c5eb8e | |
21 | --- /dev/null | |
22 | +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | |
23 | @@ -0,0 +1,206 @@ | |
24 | +#include <Base.h> | |
25 | +#include <Uefi.h> | |
26 | +#include <Library/MemoryAllocationLib.h> | |
27 | +#include <Library/BdsLib.h> | |
28 | +#include <Library/DebugLib.h> | |
29 | +#include <Library/PcdLib.h> | |
30 | +#include <Library/PrintLib.h> | |
31 | +#include <Library/UefiLib.h> | |
32 | +#include <Library/UefiApplicationEntryPoint.h> | |
33 | +#include <Library/UefiBootServicesTableLib.h> | |
34 | +#include <Library/UefiRuntimeServicesTableLib.h> | |
35 | + | |
36 | +#include <Protocol/DevicePathFromText.h> | |
37 | + | |
38 | +#include <Guid/GlobalVariable.h> | |
39 | + | |
40 | +#include <libfdt.h> | |
41 | + | |
42 | +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) | |
43 | +#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) | |
44 | +#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) | |
45 | + | |
46 | +STATIC | |
47 | +UINTN | |
48 | +IsPrintableString ( | |
49 | + IN CONST VOID* data, | |
50 | + IN UINTN len | |
51 | + ) | |
52 | +{ | |
53 | + CONST CHAR8 *s = data; | |
54 | + CONST CHAR8 *ss; | |
55 | + | |
56 | + /* zero length is not */ | |
57 | + if (len == 0) { | |
58 | + return 0; | |
59 | + } | |
60 | + | |
61 | + /* must terminate with zero */ | |
62 | + if (s[len - 1] != '\0') { | |
63 | + return 0; | |
64 | + } | |
65 | + | |
66 | + ss = s; | |
67 | + while (*s/* && isprint(*s)*/) { | |
68 | + s++; | |
69 | + } | |
70 | + | |
71 | + /* not zero, or not done yet */ | |
72 | + if (*s != '\0' || (s + 1 - ss) < len) { | |
73 | + return 0; | |
74 | + } | |
75 | + | |
76 | + return 1; | |
77 | +} | |
78 | + | |
79 | +STATIC | |
80 | +VOID | |
81 | +PrintData ( | |
82 | + IN CONST CHAR8* data, | |
83 | + IN UINTN len | |
84 | + ) | |
85 | +{ | |
86 | + UINTN i; | |
87 | + CONST CHAR8 *p = data; | |
88 | + | |
89 | + /* no data, don't print */ | |
90 | + if (len == 0) | |
91 | + return; | |
92 | + | |
93 | + if (IsPrintableString (data, len)) { | |
94 | + Print(L" = \"%a\"", (const char *)data); | |
95 | + } else if ((len % 4) == 0) { | |
96 | + Print(L" = <"); | |
97 | + for (i = 0; i < len; i += 4) { | |
98 | + Print(L"0x%08x%a", fdt32_to_cpu(GET_CELL(p)),i < (len - 4) ? " " : ""); | |
99 | + } | |
100 | + Print(L">"); | |
101 | + } else { | |
102 | + Print(L" = ["); | |
103 | + for (i = 0; i < len; i++) | |
104 | + Print(L"%02x%a", *p++, i < len - 1 ? " " : ""); | |
105 | + Print(L"]"); | |
106 | + } | |
107 | +} | |
108 | + | |
109 | +VOID | |
110 | +DumpFdt ( | |
111 | + IN VOID* FdtBlob | |
112 | + ) | |
113 | +{ | |
114 | + struct fdt_header *bph; | |
115 | + UINT32 off_dt; | |
116 | + UINT32 off_str; | |
117 | + CONST CHAR8* p_struct; | |
118 | + CONST CHAR8* p_strings; | |
119 | + CONST CHAR8* p; | |
120 | + CONST CHAR8* s; | |
121 | + CONST CHAR8* t; | |
122 | + UINT32 tag; | |
123 | + UINTN sz; | |
124 | + UINTN depth; | |
125 | + UINTN shift; | |
126 | + UINT32 version; | |
127 | + | |
128 | + depth = 0; | |
129 | + shift = 4; | |
130 | + | |
131 | + bph = FdtBlob; | |
132 | + off_dt = fdt32_to_cpu(bph->off_dt_struct); | |
133 | + off_str = fdt32_to_cpu(bph->off_dt_strings); | |
134 | + p_struct = (CONST CHAR8*)FdtBlob + off_dt; | |
135 | + p_strings = (CONST CHAR8*)FdtBlob + off_str; | |
136 | + version = fdt32_to_cpu(bph->version); | |
137 | + | |
138 | + p = p_struct; | |
139 | + while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { | |
140 | + | |
141 | + /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ | |
142 | + | |
143 | + if (tag == FDT_BEGIN_NODE) { | |
144 | + s = p; | |
145 | + p = PALIGN(p + strlen(s) + 1, 4); | |
146 | + | |
147 | + if (*s == '\0') | |
148 | + s = "/"; | |
149 | + | |
150 | + Print(L"%*s%a {\n", depth * shift, L" ", s); | |
151 | + | |
152 | + depth++; | |
153 | + continue; | |
154 | + } | |
155 | + | |
156 | + if (tag == FDT_END_NODE) { | |
157 | + depth--; | |
158 | + | |
159 | + Print(L"%*s};\n", depth * shift, L" "); | |
160 | + continue; | |
161 | + } | |
162 | + | |
163 | + if (tag == FDT_NOP) { | |
164 | + Print(L"%*s// [NOP]\n", depth * shift, L" "); | |
165 | + continue; | |
166 | + } | |
167 | + | |
168 | + if (tag != FDT_PROP) { | |
169 | + Print(L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag); | |
170 | + break; | |
171 | + } | |
172 | + sz = fdt32_to_cpu(GET_CELL(p)); | |
173 | + s = p_strings + fdt32_to_cpu(GET_CELL(p)); | |
174 | + if (version < 16 && sz >= 8) | |
175 | + p = PALIGN(p, 8); | |
176 | + t = p; | |
177 | + | |
178 | + p = PALIGN(p + sz, 4); | |
179 | + | |
180 | + Print(L"%*s%a", depth * shift, L" ", s); | |
181 | + PrintData(t, sz); | |
182 | + Print(L";\n"); | |
183 | + } | |
184 | +} | |
185 | + | |
186 | +EFI_STATUS | |
187 | +EblDumpFdt ( | |
188 | + IN UINTN Argc, | |
189 | + IN CHAR8 **Argv | |
190 | + ) | |
191 | +{ | |
192 | + EFI_STATUS Status; | |
193 | + EFI_DEVICE_PATH* FdtDevicePath; | |
194 | + VOID* FdtBlob; | |
195 | + UINTN FdtBlobSize; | |
196 | + UINTN Ret; | |
197 | + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; | |
198 | + | |
199 | + // If no FDT file is passed to the argument then get the one from the platform | |
200 | + if (Argc < 2) { | |
201 | + Status = GetEnvironmentVariable (L"Fdt",NULL,NULL,(VOID**)&FdtDevicePath); | |
202 | + if (Status == EFI_NOT_FOUND) { | |
203 | + // No set yet, get the Default Device Path | |
204 | + Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); | |
205 | + ASSERT_EFI_ERROR(Status); | |
206 | + FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); | |
207 | + } | |
208 | + } else { | |
209 | + return EFI_NOT_FOUND; | |
210 | + } | |
211 | + | |
212 | + Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, (EFI_PHYSICAL_ADDRESS*)&FdtBlob, &FdtBlobSize); | |
213 | + if (EFI_ERROR(Status)) { | |
214 | + Print (L"ERROR: Did not find the Fdt Blob.\n"); | |
215 | + return Status; | |
216 | + } | |
217 | + | |
218 | + Ret = fdt_check_header(FdtBlob); | |
219 | + if (Ret != 0) { | |
220 | + Print (L"ERROR: Device Tree header not valid (err:%d)\n",Ret); | |
221 | + return Status; | |
222 | + } | |
223 | + | |
224 | + DumpFdt (FdtBlob); | |
225 | + | |
226 | + FreePool (FdtDevicePath); | |
227 | + | |
228 | + return EFI_SUCCESS; | |
229 | +} | |
230 | diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | |
231 | old mode 100644 | |
232 | new mode 100755 | |
233 | index b75dbfb..327a794 | |
234 | --- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | |
235 | +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | |
236 | @@ -42,6 +42,12 @@ EblDumpMmu ( | |
237 | IN UINTN Argc,\r | |
238 | IN CHAR8 **Argv\r | |
239 | );\r | |
240 | + \r | |
241 | +EFI_STATUS\r | |
242 | +EblDumpFdt (\r | |
243 | + IN UINTN Argc,\r | |
244 | + IN CHAR8 **Argv\r | |
245 | + );\r | |
246 | \r | |
247 | /**\r | |
248 | Simple arm disassembler via a library\r | |
249 | @@ -416,6 +422,12 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] = | |
250 | " list all the Device Paths",\r | |
251 | NULL,\r | |
252 | EblDevicePaths\r | |
253 | + },\r | |
254 | + {\r | |
255 | + "dumpfdt",\r | |
256 | + " dump the current fdt or the one defined in the arguments",\r | |
257 | + NULL,\r | |
258 | + EblDumpFdt\r | |
259 | }\r | |
260 | };\r | |
261 | \r | |
262 | diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | |
263 | old mode 100644 | |
264 | new mode 100755 | |
265 | index 0eb71a0..9f84c07 | |
266 | --- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | |
267 | +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | |
268 | @@ -30,12 +30,14 @@ | |
269 | [Sources.common]\r | |
270 | EblCmdLib.c\r | |
271 | EblCmdMmu.c\r | |
272 | + EblCmdFdt.c\r | |
273 | \r | |
274 | [Packages]\r | |
275 | MdePkg/MdePkg.dec\r | |
276 | MdeModulePkg/MdeModulePkg.dec\r | |
277 | EmbeddedPkg/EmbeddedPkg.dec\r | |
278 | ArmPkg/ArmPkg.dec\r | |
279 | + ArmPlatformPkg/ArmPlatformPkg.dec\r | |
280 | \r | |
281 | [LibraryClasses]\r | |
282 | BaseLib\r | |
283 | @@ -45,6 +47,7 @@ | |
284 | PerformanceLib\r | |
285 | TimerLib\r | |
286 | BdsLib\r | |
287 | + FdtLib\r | |
288 | \r | |
289 | [Protocols]\r | |
290 | gEfiDebugSupportProtocolGuid\r | |
291 | @@ -53,3 +56,6 @@ | |
292 | \r | |
293 | [Guids]\r | |
294 | gEfiDebugImageInfoTableGuid\r | |
295 | +\r | |
296 | +[Pcd]\r | |
297 | + gArmPlatformTokenSpaceGuid.PcdFdtDevicePath\r | |
298 | -- | |
299 | 1.7.0.4 | |
300 |