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