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
27static struct rtas_fadump_mem_struct fdm;
28static const struct rtas_fadump_mem_struct *fdm_active;
29
30static 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 */
41static 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
98static 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
177static u64 rtas_fadump_get_bootmem_min(void)
178{
179	return RTAS_FADUMP_MIN_BOOT_MEM;
180}
181
182static 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
235static 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
260static 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
287static 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
307static 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
332static struct rtas_fadump_reg_entry* __init
333rtas_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 */
361static 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
430error_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 */
440static 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
494static 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
555static 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 */
563static 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
576static 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
588void __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