xref: /linux/arch/powerpc/platforms/pseries/rtas-fadump.c (revision ff2632d7d08edc11e8bd0629e9fcfebab25c78b4)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Firmware-Assisted Dump support on POWERVM platform.
4  *
5  * Copyright 2011, Mahesh Salgaonkar, IBM Corporation.
6  * Copyright 2019, Hari Bathini, IBM Corporation.
7  */
8 
9 #define pr_fmt(fmt) "rtas fadump: " fmt
10 
11 #include <linux/string.h>
12 #include <linux/memblock.h>
13 #include <linux/delay.h>
14 #include <linux/seq_file.h>
15 #include <linux/crash_dump.h>
16 #include <linux/of.h>
17 #include <linux/of_fdt.h>
18 
19 #include <asm/page.h>
20 #include <asm/rtas.h>
21 #include <asm/setup.h>
22 #include <asm/fadump.h>
23 #include <asm/fadump-internal.h>
24 
25 #include "rtas-fadump.h"
26 
27 static struct rtas_fadump_mem_struct fdm;
28 static const struct rtas_fadump_mem_struct *fdm_active;
29 
rtas_fadump_update_config(struct fw_dump * fadump_conf,const struct rtas_fadump_mem_struct * fdm)30 static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
31 				      const struct rtas_fadump_mem_struct *fdm)
32 {
33 	fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +
34 				       fadump_conf->boot_memory_size);
35 }
36 
37 /*
38  * This function is called in the capture kernel to get configuration details
39  * setup in the first kernel and passed to the f/w.
40  */
rtas_fadump_get_config(struct fw_dump * fadump_conf,const struct rtas_fadump_mem_struct * fdm)41 static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,
42 				   const struct rtas_fadump_mem_struct *fdm)
43 {
44 	unsigned long base, size, last_end, hole_size;
45 
46 	last_end = 0;
47 	hole_size = 0;
48 	fadump_conf->boot_memory_size = 0;
49 	fadump_conf->boot_mem_regs_cnt = 0;
50 	pr_debug("Boot memory regions:\n");
51 	for (int i = 0; i < be16_to_cpu(fdm->header.dump_num_sections); i++) {
52 		int type = be16_to_cpu(fdm->rgn[i].source_data_type);
53 		u64 addr;
54 
55 		switch (type) {
56 		case RTAS_FADUMP_CPU_STATE_DATA:
57 			addr = be64_to_cpu(fdm->rgn[i].destination_address);
58 
59 			fadump_conf->cpu_state_dest_vaddr = (u64)__va(addr);
60 			/*
61 			 * Start address of reserve dump area (permanent reservation) for
62 			 * re-registering FADump after dump capture.
63 			 */
64 			fadump_conf->reserve_dump_area_start = addr;
65 			break;
66 		case RTAS_FADUMP_HPTE_REGION:
67 			/* Not processed currently. */
68 			break;
69 		case RTAS_FADUMP_REAL_MODE_REGION:
70 			base = be64_to_cpu(fdm->rgn[i].source_address);
71 			size = be64_to_cpu(fdm->rgn[i].source_len);
72 			pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);
73 			if (!base) {
74 				fadump_conf->boot_mem_dest_addr =
75 					be64_to_cpu(fdm->rgn[i].destination_address);
76 			}
77 
78 			fadump_conf->boot_mem_addr[fadump_conf->boot_mem_regs_cnt] = base;
79 			fadump_conf->boot_mem_sz[fadump_conf->boot_mem_regs_cnt] = size;
80 			fadump_conf->boot_memory_size += size;
81 			hole_size += (base - last_end);
82 			last_end = base + size;
83 			fadump_conf->boot_mem_regs_cnt++;
84 			break;
85 		case RTAS_FADUMP_PARAM_AREA:
86 			fadump_conf->param_area = be64_to_cpu(fdm->rgn[i].destination_address);
87 			break;
88 		default:
89 			pr_warn("Section type %d unsupported on this kernel. Ignoring!\n", type);
90 			break;
91 		}
92 	}
93 	fadump_conf->boot_mem_top = fadump_conf->boot_memory_size + hole_size;
94 
95 	rtas_fadump_update_config(fadump_conf, fdm);
96 }
97 
rtas_fadump_init_mem_struct(struct fw_dump * fadump_conf)98 static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
99 {
100 	u64 addr = fadump_conf->reserve_dump_area_start;
101 	u16 sec_cnt = 0;
102 
103 	memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));
104 	addr = addr & PAGE_MASK;
105 
106 	fdm.header.dump_format_version = cpu_to_be32(0x00000001);
107 	fdm.header.dump_status_flag = 0;
108 	fdm.header.offset_first_dump_section =
109 		cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct, rgn));
110 
111 	/*
112 	 * Fields for disk dump option.
113 	 * We are not using disk dump option, hence set these fields to 0.
114 	 */
115 	fdm.header.dd_block_size = 0;
116 	fdm.header.dd_block_offset = 0;
117 	fdm.header.dd_num_blocks = 0;
118 	fdm.header.dd_offset_disk_path = 0;
119 
120 	/* set 0 to disable an automatic dump-reboot. */
121 	fdm.header.max_time_auto = 0;
122 
123 	/* Kernel dump sections */
124 	/* cpu state data section. */
125 	fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
126 	fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
127 	fdm.rgn[sec_cnt].source_address = 0;
128 	fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->cpu_state_data_size);
129 	fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
130 	addr += fadump_conf->cpu_state_data_size;
131 	sec_cnt++;
132 
133 	/* hpte region section */
134 	fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
135 	fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
136 	fdm.rgn[sec_cnt].source_address = 0;
137 	fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->hpte_region_size);
138 	fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
139 	addr += fadump_conf->hpte_region_size;
140 	sec_cnt++;
141 
142 	/*
143 	 * Align boot memory area destination address to page boundary to
144 	 * be able to mmap read this area in the vmcore.
145 	 */
146 	addr = PAGE_ALIGN(addr);
147 
148 	/* First boot memory region destination address */
149 	fadump_conf->boot_mem_dest_addr = addr;
150 	for (int i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) {
151 		/* Boot memory regions */
152 		fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
153 		fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);
154 		fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->boot_mem_addr[i]);
155 		fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->boot_mem_sz[i]);
156 		fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
157 		addr += fadump_conf->boot_mem_sz[i];
158 		sec_cnt++;
159 	}
160 
161 	/* Parameters area */
162 	if (fadump_conf->param_area) {
163 		fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
164 		fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_PARAM_AREA);
165 		fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->param_area);
166 		fdm.rgn[sec_cnt].source_len = cpu_to_be64(COMMAND_LINE_SIZE);
167 		fdm.rgn[sec_cnt].destination_address = cpu_to_be64(fadump_conf->param_area);
168 		sec_cnt++;
169 	}
170 	fdm.header.dump_num_sections = cpu_to_be16(sec_cnt);
171 
172 	rtas_fadump_update_config(fadump_conf, &fdm);
173 
174 	return addr;
175 }
176 
rtas_fadump_get_bootmem_min(void)177 static u64 rtas_fadump_get_bootmem_min(void)
178 {
179 	return RTAS_FADUMP_MIN_BOOT_MEM;
180 }
181 
rtas_fadump_register(struct fw_dump * fadump_conf)182 static int rtas_fadump_register(struct fw_dump *fadump_conf)
183 {
184 	unsigned int wait_time, fdm_size;
185 	int rc, err = -EIO;
186 
187 	/*
188 	 * Platform requires the exact size of the Dump Memory Structure.
189 	 * Avoid including any unused rgns in the calculation, as this
190 	 * could result in a parameter error (-3) from the platform.
191 	 */
192 	fdm_size = sizeof(struct rtas_fadump_section_header);
193 	fdm_size += be16_to_cpu(fdm.header.dump_num_sections) * sizeof(struct rtas_fadump_section);
194 
195 	/* TODO: Add upper time limit for the delay */
196 	do {
197 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
198 				NULL, FADUMP_REGISTER, &fdm, fdm_size);
199 
200 		wait_time = rtas_busy_delay_time(rc);
201 		if (wait_time)
202 			mdelay(wait_time);
203 
204 	} while (wait_time);
205 
206 	switch (rc) {
207 	case 0:
208 		pr_info("Registration is successful!\n");
209 		fadump_conf->dump_registered = 1;
210 		err = 0;
211 		break;
212 	case -1:
213 		pr_err("Failed to register. Hardware Error(%d).\n", rc);
214 		break;
215 	case -3:
216 		if (!is_fadump_reserved_mem_contiguous())
217 			pr_err("Can't have holes in reserved memory area.\n");
218 
219 		pr_err("Failed to register. Parameter Error(%d).\n", rc);
220 		err = -EINVAL;
221 		break;
222 	case -9:
223 		pr_err("Already registered!\n");
224 		fadump_conf->dump_registered = 1;
225 		err = -EEXIST;
226 		break;
227 	default:
228 		pr_err("Failed to register. Unknown Error(%d).\n", rc);
229 		break;
230 	}
231 
232 	return err;
233 }
234 
rtas_fadump_unregister(struct fw_dump * fadump_conf)235 static int rtas_fadump_unregister(struct fw_dump *fadump_conf)
236 {
237 	unsigned int wait_time;
238 	int rc;
239 
240 	/* TODO: Add upper time limit for the delay */
241 	do {
242 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
243 				NULL, FADUMP_UNREGISTER, &fdm,
244 				sizeof(struct rtas_fadump_mem_struct));
245 
246 		wait_time = rtas_busy_delay_time(rc);
247 		if (wait_time)
248 			mdelay(wait_time);
249 	} while (wait_time);
250 
251 	if (rc) {
252 		pr_err("Failed to un-register - unexpected error(%d).\n", rc);
253 		return -EIO;
254 	}
255 
256 	fadump_conf->dump_registered = 0;
257 	return 0;
258 }
259 
rtas_fadump_invalidate(struct fw_dump * fadump_conf)260 static int rtas_fadump_invalidate(struct fw_dump *fadump_conf)
261 {
262 	unsigned int wait_time;
263 	int rc;
264 
265 	/* TODO: Add upper time limit for the delay */
266 	do {
267 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
268 				NULL, FADUMP_INVALIDATE, fdm_active,
269 				sizeof(struct rtas_fadump_mem_struct));
270 
271 		wait_time = rtas_busy_delay_time(rc);
272 		if (wait_time)
273 			mdelay(wait_time);
274 	} while (wait_time);
275 
276 	if (rc) {
277 		pr_err("Failed to invalidate - unexpected error (%d).\n", rc);
278 		return -EIO;
279 	}
280 
281 	fadump_conf->dump_active = 0;
282 	fdm_active = NULL;
283 	return 0;
284 }
285 
286 #define RTAS_FADUMP_GPR_MASK		0xffffff0000000000
rtas_fadump_gpr_index(u64 id)287 static inline int rtas_fadump_gpr_index(u64 id)
288 {
289 	char str[3];
290 	int i = -1;
291 
292 	if ((id & RTAS_FADUMP_GPR_MASK) == fadump_str_to_u64("GPR")) {
293 		/* get the digits at the end */
294 		id &= ~RTAS_FADUMP_GPR_MASK;
295 		id >>= 24;
296 		str[2] = '\0';
297 		str[1] = id & 0xff;
298 		str[0] = (id >> 8) & 0xff;
299 		if (kstrtoint(str, 10, &i))
300 			i = -EINVAL;
301 		if (i > 31)
302 			i = -1;
303 	}
304 	return i;
305 }
306 
rtas_fadump_set_regval(struct pt_regs * regs,u64 reg_id,u64 reg_val)307 static void __init rtas_fadump_set_regval(struct pt_regs *regs, u64 reg_id, u64 reg_val)
308 {
309 	int i;
310 
311 	i = rtas_fadump_gpr_index(reg_id);
312 	if (i >= 0)
313 		regs->gpr[i] = (unsigned long)reg_val;
314 	else if (reg_id == fadump_str_to_u64("NIA"))
315 		regs->nip = (unsigned long)reg_val;
316 	else if (reg_id == fadump_str_to_u64("MSR"))
317 		regs->msr = (unsigned long)reg_val;
318 	else if (reg_id == fadump_str_to_u64("CTR"))
319 		regs->ctr = (unsigned long)reg_val;
320 	else if (reg_id == fadump_str_to_u64("LR"))
321 		regs->link = (unsigned long)reg_val;
322 	else if (reg_id == fadump_str_to_u64("XER"))
323 		regs->xer = (unsigned long)reg_val;
324 	else if (reg_id == fadump_str_to_u64("CR"))
325 		regs->ccr = (unsigned long)reg_val;
326 	else if (reg_id == fadump_str_to_u64("DAR"))
327 		regs->dar = (unsigned long)reg_val;
328 	else if (reg_id == fadump_str_to_u64("DSISR"))
329 		regs->dsisr = (unsigned long)reg_val;
330 }
331 
332 static struct rtas_fadump_reg_entry* __init
rtas_fadump_read_regs(struct rtas_fadump_reg_entry * reg_entry,struct pt_regs * regs)333 rtas_fadump_read_regs(struct rtas_fadump_reg_entry *reg_entry,
334 		      struct pt_regs *regs)
335 {
336 	memset(regs, 0, sizeof(struct pt_regs));
337 
338 	while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {
339 		rtas_fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
340 				       be64_to_cpu(reg_entry->reg_value));
341 		reg_entry++;
342 	}
343 	reg_entry++;
344 	return reg_entry;
345 }
346 
347 /*
348  * Read CPU state dump data and convert it into ELF notes.
349  * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
350  * used to access the data to allow for additional fields to be added without
351  * affecting compatibility. Each list of registers for a CPU starts with
352  * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
353  * 8 Byte ASCII identifier and 8 Byte register value. The register entry
354  * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
355  * of register value. For more details refer to PAPR document.
356  *
357  * Only for the crashing cpu we ignore the CPU dump data and get exact
358  * state from fadump crash info structure populated by first kernel at the
359  * time of crash.
360  */
rtas_fadump_build_cpu_notes(struct fw_dump * fadump_conf)361 static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
362 {
363 	struct rtas_fadump_reg_save_area_header *reg_header;
364 	struct fadump_crash_info_header *fdh = NULL;
365 	struct rtas_fadump_reg_entry *reg_entry;
366 	u32 num_cpus, *note_buf;
367 	int i, rc = 0, cpu = 0;
368 	struct pt_regs regs;
369 	void *vaddr;
370 
371 	vaddr = (void *)fadump_conf->cpu_state_dest_vaddr;
372 
373 	reg_header = vaddr;
374 	if (be64_to_cpu(reg_header->magic_number) !=
375 	    fadump_str_to_u64("REGSAVE")) {
376 		pr_err("Unable to read register save area.\n");
377 		return -ENOENT;
378 	}
379 
380 	pr_debug("--------CPU State Data------------\n");
381 	pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
382 	pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
383 
384 	vaddr += be32_to_cpu(reg_header->num_cpu_offset);
385 	num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
386 	pr_debug("NumCpus     : %u\n", num_cpus);
387 	vaddr += sizeof(u32);
388 	reg_entry = (struct rtas_fadump_reg_entry *)vaddr;
389 
390 	rc = fadump_setup_cpu_notes_buf(num_cpus);
391 	if (rc != 0)
392 		return rc;
393 
394 	note_buf = (u32 *)fadump_conf->cpu_notes_buf_vaddr;
395 
396 	if (fadump_conf->fadumphdr_addr)
397 		fdh = __va(fadump_conf->fadumphdr_addr);
398 
399 	for (i = 0; i < num_cpus; i++) {
400 		if (be64_to_cpu(reg_entry->reg_id) !=
401 		    fadump_str_to_u64("CPUSTRT")) {
402 			pr_err("Unable to read CPU state data\n");
403 			rc = -ENOENT;
404 			goto error_out;
405 		}
406 		/* Lower 4 bytes of reg_value contains logical cpu id */
407 		cpu = (be64_to_cpu(reg_entry->reg_value) &
408 		       RTAS_FADUMP_CPU_ID_MASK);
409 		if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_mask)) {
410 			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
411 			continue;
412 		}
413 		pr_debug("Reading register data for cpu %d...\n", cpu);
414 		if (fdh && fdh->crashing_cpu == cpu) {
415 			regs = fdh->regs;
416 			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
417 			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
418 		} else {
419 			reg_entry++;
420 			reg_entry = rtas_fadump_read_regs(reg_entry, &regs);
421 			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
422 		}
423 	}
424 	final_note(note_buf);
425 
426 	pr_debug("Updating elfcore header (%llx) with cpu notes\n", fadump_conf->elfcorehdr_addr);
427 	fadump_update_elfcore_header((char *)fadump_conf->elfcorehdr_addr);
428 	return 0;
429 
430 error_out:
431 	fadump_free_cpu_notes_buf();
432 	return rc;
433 
434 }
435 
436 /*
437  * Validate and process the dump data stored by the firmware, and update
438  * the CPU notes of elfcorehdr.
439  */
rtas_fadump_process(struct fw_dump * fadump_conf)440 static int __init rtas_fadump_process(struct fw_dump *fadump_conf)
441 {
442 	if (!fdm_active || !fadump_conf->fadumphdr_addr)
443 		return -EINVAL;
444 
445 	/* Check if the dump data is valid. */
446 	for (int i = 0; i < be16_to_cpu(fdm_active->header.dump_num_sections); i++) {
447 		int type = be16_to_cpu(fdm_active->rgn[i].source_data_type);
448 		int rc = 0;
449 
450 		switch (type) {
451 		case RTAS_FADUMP_CPU_STATE_DATA:
452 		case RTAS_FADUMP_HPTE_REGION:
453 		case RTAS_FADUMP_REAL_MODE_REGION:
454 			if (fdm_active->rgn[i].error_flags != 0) {
455 				pr_err("Dump taken by platform is not valid (%d)\n", i);
456 				rc = -EINVAL;
457 			}
458 			if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len) {
459 				pr_err("Dump taken by platform is incomplete (%d)\n", i);
460 				rc = -EINVAL;
461 			}
462 			if (rc) {
463 				pr_warn("Region type: %u src addr: 0x%llx dest addr: 0x%llx\n",
464 					be16_to_cpu(fdm_active->rgn[i].source_data_type),
465 					be64_to_cpu(fdm_active->rgn[i].source_address),
466 					be64_to_cpu(fdm_active->rgn[i].destination_address));
467 				return rc;
468 			}
469 			break;
470 		case RTAS_FADUMP_PARAM_AREA:
471 			if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len ||
472 			    fdm_active->rgn[i].error_flags != 0) {
473 				pr_warn("Failed to process additional parameters! Proceeding anyway..\n");
474 				fadump_conf->param_area = 0;
475 			}
476 			break;
477 		default:
478 			/*
479 			 * If the first/crashed kernel added a new region type that the
480 			 * second/fadump kernel doesn't recognize, skip it and process
481 			 * assuming backward compatibility.
482 			 */
483 			pr_warn("Unknown region found: type: %u src addr: 0x%llx dest addr: 0x%llx\n",
484 				be16_to_cpu(fdm_active->rgn[i].source_data_type),
485 				be64_to_cpu(fdm_active->rgn[i].source_address),
486 				be64_to_cpu(fdm_active->rgn[i].destination_address));
487 			break;
488 		}
489 	}
490 
491 	return rtas_fadump_build_cpu_notes(fadump_conf);
492 }
493 
rtas_fadump_region_show(struct fw_dump * fadump_conf,struct seq_file * m)494 static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
495 				    struct seq_file *m)
496 {
497 	const struct rtas_fadump_mem_struct *fdm_ptr;
498 
499 	if (fdm_active)
500 		fdm_ptr = fdm_active;
501 	else
502 		fdm_ptr = &fdm;
503 
504 
505 	for (int i = 0; i < be16_to_cpu(fdm_ptr->header.dump_num_sections); i++) {
506 		int type = be16_to_cpu(fdm_ptr->rgn[i].source_data_type);
507 
508 		switch (type) {
509 		case RTAS_FADUMP_CPU_STATE_DATA:
510 			seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
511 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address),
512 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
513 				   be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
514 				   be64_to_cpu(fdm_ptr->rgn[i].source_len),
515 				   be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
516 			break;
517 		case RTAS_FADUMP_HPTE_REGION:
518 			seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
519 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address),
520 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
521 				   be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
522 				   be64_to_cpu(fdm_ptr->rgn[i].source_len),
523 				   be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
524 			break;
525 		case RTAS_FADUMP_REAL_MODE_REGION:
526 			seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",
527 				   be64_to_cpu(fdm_ptr->rgn[i].source_address),
528 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address));
529 			seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
530 				   be64_to_cpu(fdm_ptr->rgn[i].source_len),
531 				   be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));
532 			break;
533 		case RTAS_FADUMP_PARAM_AREA:
534 			seq_printf(m, "\n[%#016llx-%#016llx]: cmdline append: '%s'\n",
535 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address),
536 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address) +
537 				   be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,
538 				   (char *)__va(be64_to_cpu(fdm_ptr->rgn[i].destination_address)));
539 			break;
540 		default:
541 			seq_printf(m, "Unknown region type %d : Src: %#016llx, Dest: %#016llx, ",
542 				   type, be64_to_cpu(fdm_ptr->rgn[i].source_address),
543 				   be64_to_cpu(fdm_ptr->rgn[i].destination_address));
544 			break;
545 		}
546 	}
547 
548 	/* Dump is active. Show preserved area start address. */
549 	if (fdm_active) {
550 		seq_printf(m, "\nMemory above %#016llx is reserved for saving crash dump\n",
551 			   fadump_conf->boot_mem_top);
552 	}
553 }
554 
rtas_fadump_trigger(struct fadump_crash_info_header * fdh,const char * msg)555 static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
556 				const char *msg)
557 {
558 	/* Call ibm,os-term rtas call to trigger firmware assisted dump */
559 	rtas_os_term((char *)msg);
560 }
561 
562 /* FADUMP_MAX_MEM_REGS or lower */
rtas_fadump_max_boot_mem_rgns(void)563 static int rtas_fadump_max_boot_mem_rgns(void)
564 {
565 	/*
566 	 * Version 1 of Kernel Assisted Dump Memory Structure (PAPR) supports 10 sections.
567 	 * With one each section taken for CPU state data & HPTE respectively, 8 sections
568 	 * can be used for boot memory regions.
569 	 *
570 	 * If new region(s) is(are) defined, maximum boot memory regions will decrease
571 	 * proportionally.
572 	 */
573 	return RTAS_FADUMP_MAX_BOOT_MEM_REGS;
574 }
575 
576 static struct fadump_ops rtas_fadump_ops = {
577 	.fadump_init_mem_struct		= rtas_fadump_init_mem_struct,
578 	.fadump_get_bootmem_min		= rtas_fadump_get_bootmem_min,
579 	.fadump_register		= rtas_fadump_register,
580 	.fadump_unregister		= rtas_fadump_unregister,
581 	.fadump_invalidate		= rtas_fadump_invalidate,
582 	.fadump_process			= rtas_fadump_process,
583 	.fadump_region_show		= rtas_fadump_region_show,
584 	.fadump_trigger			= rtas_fadump_trigger,
585 	.fadump_max_boot_mem_rgns	= rtas_fadump_max_boot_mem_rgns,
586 };
587 
rtas_fadump_dt_scan(struct fw_dump * fadump_conf,u64 node)588 void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
589 {
590 	int i, size, num_sections;
591 	const __be32 *sections;
592 	const __be32 *token;
593 
594 	/*
595 	 * Check if Firmware Assisted dump is supported. if yes, check
596 	 * if dump has been initiated on last reboot.
597 	 */
598 	token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);
599 	if (!token)
600 		return;
601 
602 	fadump_conf->ibm_configure_kernel_dump	= be32_to_cpu(*token);
603 	fadump_conf->ops			= &rtas_fadump_ops;
604 	fadump_conf->fadump_supported		= 1;
605 	fadump_conf->param_area_supported	= 1;
606 
607 	/* Firmware supports 64-bit value for size, align it to pagesize. */
608 	fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
609 
610 	/*
611 	 * The 'ibm,kernel-dump' rtas node is present only if there is
612 	 * dump data waiting for us.
613 	 */
614 	fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
615 	if (fdm_active) {
616 		pr_info("Firmware-assisted dump is active.\n");
617 		fadump_conf->dump_active = 1;
618 		rtas_fadump_get_config(fadump_conf, (void *)__pa(fdm_active));
619 	}
620 
621 	/* Get the sizes required to store dump data for the firmware provided
622 	 * dump sections.
623 	 * For each dump section type supported, a 32bit cell which defines
624 	 * the ID of a supported section followed by two 32 bit cells which
625 	 * gives the size of the section in bytes.
626 	 */
627 	sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
628 					&size);
629 
630 	if (!sections)
631 		return;
632 
633 	num_sections = size / (3 * sizeof(u32));
634 
635 	for (i = 0; i < num_sections; i++, sections += 3) {
636 		u32 type = (u32)of_read_number(sections, 1);
637 
638 		switch (type) {
639 		case RTAS_FADUMP_CPU_STATE_DATA:
640 			fadump_conf->cpu_state_data_size =
641 					of_read_ulong(&sections[1], 2);
642 			break;
643 		case RTAS_FADUMP_HPTE_REGION:
644 			fadump_conf->hpte_region_size =
645 					of_read_ulong(&sections[1], 2);
646 			break;
647 		}
648 	}
649 }
650