1 /* Copyright 2013-2019 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /* Given a hdata dump, output the device tree. */
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/mman.h>
20 #include <fcntl.h>
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <stdint.h>
25 #include <mem_region-malloc.h>
26
27 #include <interrupts.h>
28 #include <bitutils.h>
29
30 #include <skiboot-valgrind.h>
31
32 #include "../../libfdt/fdt.c"
33 #include "../../libfdt/fdt_ro.c"
34 #include "../../libfdt/fdt_sw.c"
35 #include "../../libfdt/fdt_strerror.c"
36
37 struct dt_node *opal_node;
38
39 /* Our actual map. */
40 static void *spira_heap;
41 static off_t spira_heap_size;
42 static uint64_t base_addr;
43
44 /* Override ntuple_addr. */
45 #define ntuple_addr ntuple_addr
46 struct spira_ntuple;
47 static void *ntuple_addr(const struct spira_ntuple *n);
48
49 /* Stuff which core expects. */
50 #define __this_cpu ((struct cpu_thread *)NULL)
51
52 unsigned long tb_hz = 512000000;
53
54 /* Don't include processor-specific stuff. */
55 #define __PROCESSOR_H
56 /* PVR bits */
57 #define SPR_PVR_TYPE 0xffff0000
58 #define SPR_PVR_VERS_MAJ 0x00000f00
59 #define SPR_PVR_VERS_MIN 0x000000ff
60
61 #define PVR_TYPE(_pvr) GETFIELD(SPR_PVR_TYPE, _pvr)
62 #define PVR_VERS_MAJ(_pvr) GETFIELD(SPR_PVR_VERS_MAJ, _pvr)
63 #define PVR_VERS_MIN(_pvr) GETFIELD(SPR_PVR_VERS_MIN, _pvr)
64
65 /* PVR definitions - copied from skiboot include/processor.h */
66 #define PVR_TYPE_P8E 0x004b
67 #define PVR_TYPE_P8 0x004d
68 #define PVR_TYPE_P8NVL 0x004c
69 #define PVR_TYPE_P9 0x004e
70 #define PVR_TYPE_P9P 0x004f
71 #define PVR_P8E 0x004b0201
72 #define PVR_P8 0x004d0200
73 #define PVR_P8NVL 0x004c0100
74 #define PVR_P9 0x004e0200
75 #define PVR_P9P 0x004f0100
76
77 #define SPR_PVR 0x11f /* RO: Processor version register */
78
79 #define __CPU_H
80 struct cpu_thread {
81 uint32_t pir;
82 uint32_t chip_id;
83 };
84 struct cpu_job *__cpu_queue_job(struct cpu_thread *cpu,
85 const char *name,
86 void (*func)(void *data), void *data,
87 bool no_return);
88 void cpu_wait_job(struct cpu_job *job, bool free_it);
89 void cpu_process_local_jobs(void);
90 struct cpu_job *cpu_queue_job_on_node(uint32_t chip_id,
91 const char *name,
92 void (*func)(void *data), void *data);
cpu_queue_job(struct cpu_thread * cpu,const char * name,void (* func)(void * data),void * data)93 static inline struct cpu_job *cpu_queue_job(struct cpu_thread *cpu,
94 const char *name,
95 void (*func)(void *data),
96 void *data)
97 {
98 return __cpu_queue_job(cpu, name, func, data, false);
99 }
100
101 struct cpu_thread __boot_cpu, *boot_cpu = &__boot_cpu;
102 static unsigned long fake_pvr = PVR_P8;
103
mfspr(unsigned int spr)104 static inline unsigned long mfspr(unsigned int spr)
105 {
106 assert(spr == SPR_PVR);
107 return fake_pvr;
108 }
109
add_ics_node(void)110 struct dt_node *add_ics_node(void)
111 {
112 return NULL;
113 }
114
115 // Copied from processor.h:
is_power9n(uint32_t version)116 static inline bool is_power9n(uint32_t version)
117 {
118 if (PVR_TYPE(version) != PVR_TYPE_P9)
119 return false;
120 /*
121 * Bit 13 tells us:
122 * 0 = Scale out (aka Nimbus)
123 * 1 = Scale up (aka Cumulus)
124 */
125 if ((version >> 13) & 1)
126 return false;
127 return true;
128 }
129
130 #include <config.h>
131 #include <bitutils.h>
132
133 /* Your pointers won't be correct, that's OK. */
134 #define spira_check_ptr spira_check_ptr
135
136 static bool spira_check_ptr(const void *ptr, const char *file, unsigned int line);
137
138 /* should probably check this */
139 #define BITS_PER_LONG 64
140 /* not used, just needs to exist */
141 #define cpu_max_pir 0x7
142
143 #include "../cpu-common.c"
144 #include "../fsp.c"
145 #include "../hdif.c"
146 #include "../iohub.c"
147 #include "../memory.c"
148 #include "../paca.c"
149 #include "../pcia.c"
150 #include "../spira.c"
151 #include "../vpd.c"
152 #include "../vpd-common.c"
153 #include "../slca.c"
154 #include "../hostservices.c"
155 #include "../i2c.c"
156 #include "../tpmrel.c"
157 #include "../../core/vpd.c"
158 #include "../../core/device.c"
159 #include "../../core/chip.c"
160 #include "../../test/dt_common.c"
161 #include "../../core/fdt.c"
162 #include "../../hw/phys-map.c"
163 #include "../../core/mem_region.c"
164
165 #include <err.h>
166
167 #include <op-panel.h>
168
fsp_present()169 bool fsp_present()
170 {
171 return false;
172 }
173
op_display(enum op_severity s,enum op_module m,uint16_t code)174 void op_display(enum op_severity s, enum op_module m, uint16_t code)
175 {
176 fprintf(stderr, "op_panel Severity: 0x%x (%s), module %x, %x\n",
177 s, (s == OP_FATAL) ? "FATAL" : "non-fatal",
178 m, code);
179 if (s == OP_FATAL)
180 exit(EXIT_FAILURE);
181 }
182
183 char __rodata_start[1], __rodata_end[1];
184
185 enum proc_gen proc_gen = proc_gen_p8;
186
spira_check_ptr(const void * ptr,const char * file,unsigned int line)187 static bool spira_check_ptr(const void *ptr, const char *file, unsigned int line)
188 {
189 if (!ptr)
190 return false;
191 /* we fake the SPIRA pointer as it's relative to where it was loaded
192 * on real hardware */
193 (void)file;
194 (void)line;
195 return true;
196 }
197
ntuple_addr(const struct spira_ntuple * n)198 static void *ntuple_addr(const struct spira_ntuple *n)
199 {
200 uint64_t addr = be64_to_cpu(n->addr);
201 if (n->addr == 0)
202 return NULL;
203 if (addr < base_addr) {
204 fprintf(stderr, "assert failed: addr >= base_addr (%"PRIu64" >= %"PRIu64")\n", addr, base_addr);
205 exit(EXIT_FAILURE);
206 }
207 if (addr >= base_addr + spira_heap_size) {
208 fprintf(stderr, "assert failed: addr not in spira_heap\n");
209 exit(EXIT_FAILURE);
210 }
211 return spira_heap + ((unsigned long)addr - base_addr);
212 }
213
214 /* Make sure valgrind knows these are undefined bytes. */
undefined_bytes(void * p,size_t len)215 static void undefined_bytes(void *p, size_t len)
216 {
217 VALGRIND_MAKE_MEM_UNDEFINED(p, len);
218 }
219
hash_prop(const struct dt_property * p)220 static u32 hash_prop(const struct dt_property *p)
221 {
222 u32 i, hash = 0;
223
224 /* a stupid checksum */
225 for (i = 0; i < p->len; i++)
226 hash += (((signed char)p->prop[i] & ~0x10) + 1) * i;
227
228 return hash;
229 }
230
231 /*
232 * This filters out VPD blobs and other annoyances from the devicetree output.
233 * We don't actually care about the contents of the blob, we just want to make
234 * sure it's there and that we aren't accidently corrupting the contents.
235 */
squash_blobs(struct dt_node * root)236 static void squash_blobs(struct dt_node *root)
237 {
238 struct dt_node *n;
239 struct dt_property *p;
240
241 list_for_each(&root->properties, p, list) {
242 if (strstarts(p->name, DT_PRIVATE))
243 continue;
244
245 /*
246 * Consider any property larger than 512 bytes a blob that can
247 * be removed. This number was picked out of thin in so don't
248 * feel bad about changing it.
249 */
250 if (p->len > 512) {
251 u32 hash = hash_prop(p);
252 u32 *val = (u32 *) p->prop;
253
254 /* Add a sentinel so we know it was truncated */
255 val[0] = cpu_to_be32(0xcafebeef);
256 val[1] = cpu_to_be32(p->len);
257 val[2] = cpu_to_be32(hash);
258 p->len = 3 * sizeof(u32);
259 }
260 }
261
262 list_for_each(&root->children, n, list)
263 squash_blobs(n);
264 }
265
dump_hdata_fdt(struct dt_node * root)266 static void dump_hdata_fdt(struct dt_node *root)
267 {
268 struct dt_node *n;
269 void *fdt_blob;
270
271 /* delete some properties that hardcode pointers */
272 dt_for_each_node(dt_root, n) {
273 struct dt_property *base;
274
275 /*
276 * sml-base is a raw pointer into the HDAT area so it changes
277 * on each execution of hdata_to_dt. Work around this by
278 * zeroing it.
279 */
280 base = __dt_find_property(n, "linux,sml-base");
281 if (base)
282 memset(base->prop, 0, base->len);
283 }
284
285 fdt_blob = create_dtb(root, false);
286
287 if (!fdt_blob) {
288 fprintf(stderr, "Unable to make flattened DT, no FDT written\n");
289 return;
290 }
291
292 fwrite(fdt_blob, fdt_totalsize(fdt_blob), 1, stdout);
293
294 free(fdt_blob);
295 }
296
main(int argc,char * argv[])297 int main(int argc, char *argv[])
298 {
299 int fd, r, i = 0, opt_count = 0;
300 bool verbose = false, quiet = false, new_spira = false, blobs = false;
301
302 while (argv[++i]) {
303 if (strcmp(argv[i], "-v") == 0) {
304 verbose = true;
305 opt_count++;
306 } else if (strcmp(argv[i], "-q") == 0) {
307 quiet = true;
308 opt_count++;
309 } else if (strcmp(argv[i], "-s") == 0) {
310 new_spira = true;
311 opt_count++;
312 } else if (strcmp(argv[i], "-b") == 0) {
313 blobs = true;
314 opt_count++;
315 } else if (strcmp(argv[i], "-8E") == 0) {
316 fake_pvr = PVR_P8;
317 proc_gen = proc_gen_p8;
318 opt_count++;
319 } else if (strcmp(argv[i], "-8") == 0) {
320 fake_pvr = PVR_P8;
321 proc_gen = proc_gen_p8;
322 opt_count++;
323 } else if (strcmp(argv[i], "-9") == 0) {
324 fake_pvr = PVR_P9;
325 proc_gen = proc_gen_p9;
326 opt_count++;
327 } else if (strcmp(argv[i], "-9P") == 0) {
328 fake_pvr = PVR_P9P;
329 proc_gen = proc_gen_p9;
330 opt_count++;
331 }
332 }
333
334 argc -= opt_count;
335 argv += opt_count;
336 if (argc != 3) {
337 errx(1, "Converts HDAT dumps to DTB.\n"
338 "\n"
339 "Usage:\n"
340 " hdata <opts> <spira-dump> <heap-dump>\n"
341 " hdata <opts> -s <spirah-dump> <spiras-dump>\n"
342 "Options: \n"
343 " -v Verbose\n"
344 " -q Quiet mode\n"
345 " -b Keep blobs in the output\n"
346 "\n"
347 " -8 Force PVR to POWER8\n"
348 " -8E Force PVR to POWER8E\n"
349 " -9 Force PVR to POWER9 (nimbus)\n"
350 "\n"
351 "When no PVR is specified -7 is assumed"
352 "\n"
353 "Pipe to 'dtc -I dtb -O dts' for human readable output\n");
354 }
355
356 phys_map_init();
357
358 /* Copy in spira dump (assumes little has changed!). */
359 if (new_spira) {
360 fd = open(argv[1], O_RDONLY);
361 if (fd < 0)
362 err(1, "opening %s", argv[1]);
363 r = read(fd, &spirah, sizeof(spirah));
364 if (r < sizeof(spirah.hdr))
365 err(1, "reading %s gave %i", argv[1], r);
366 if (verbose)
367 printf("verbose: read spirah %u bytes\n", r);
368 close(fd);
369
370 undefined_bytes((void *)&spirah + r, sizeof(spirah) - r);
371
372 base_addr = be64_to_cpu(spirah.ntuples.hs_data_area.addr);
373 } else {
374 fd = open(argv[1], O_RDONLY);
375 if (fd < 0)
376 err(1, "opening %s", argv[1]);
377 r = read(fd, &spira, sizeof(spira));
378 if (r < sizeof(spira.hdr))
379 err(1, "reading %s gave %i", argv[1], r);
380 if (verbose)
381 printf("verbose: read spira %u bytes\n", r);
382 close(fd);
383
384 undefined_bytes((void *)&spira + r, sizeof(spira) - r);
385
386 base_addr = be64_to_cpu(spira.ntuples.heap.addr);
387 }
388
389 if (!base_addr)
390 errx(1, "Invalid base addr");
391 if (verbose)
392 printf("verbose: map.base_addr = %llx\n", (long long)base_addr);
393
394 fd = open(argv[2], O_RDONLY);
395 if (fd < 0)
396 err(1, "opening %s", argv[2]);
397 spira_heap_size = lseek(fd, 0, SEEK_END);
398 if (spira_heap_size < 0)
399 err(1, "lseek on %s", argv[2]);
400 spira_heap = mmap(NULL, spira_heap_size, PROT_READ, MAP_SHARED, fd, 0);
401 if (spira_heap == MAP_FAILED)
402 err(1, "mmaping %s", argv[3]);
403 if (verbose)
404 printf("verbose: mapped %zu at %p\n",
405 spira_heap_size, spira_heap);
406 close(fd);
407
408 if (new_spira)
409 spiras = (struct spiras *)spira_heap;
410
411 if (quiet) {
412 fclose(stdout);
413 fclose(stderr);
414 }
415
416 dt_root = dt_new_root("");
417
418 if(parse_hdat(false) < 0) {
419 fprintf(stderr, "FATAL ERROR parsing HDAT\n");
420 dt_free(dt_root);
421 exit(EXIT_FAILURE);
422 }
423
424 mem_region_init();
425 mem_region_release_unused();
426
427 if (!blobs)
428 squash_blobs(dt_root);
429
430 if (!quiet)
431 dump_hdata_fdt(dt_root);
432
433 dt_free(dt_root);
434 return 0;
435 }
436