arch/powerpc/kernel/fadump.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/fadump.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/fadump.c
Extension
.c
Size
49873 bytes
Lines
1879
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (memblock_reserve(fw_dump.param_area, COMMAND_LINE_SIZE)) {
			pr_warn("WARNING: Can't use additional parameters area!\n");
			fw_dump.param_area = 0;
			return;
		}
	}

	append_args = (char *)fw_dump.param_area;
	len = strlen(boot_command_line);

	/*
	 * Too late to fail even if cmdline size exceeds. Truncate additional parameters
	 * to cmdline size and proceed anyway.
	 */
	if (len + strlen(append_args) >= COMMAND_LINE_SIZE - 1)
		pr_warn("WARNING: Appending parameters exceeds cmdline size. Truncating!\n");

	pr_debug("Cmdline: %s\n", boot_command_line);
	snprintf(boot_command_line + len, COMMAND_LINE_SIZE - len, " %s", append_args);
	pr_info("Updated cmdline: %s\n", boot_command_line);
}

/* Scan the Firmware Assisted dump configuration details. */
int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
				      int depth, void *data)
{
	if (depth == 0) {
		early_init_dt_scan_reserved_ranges(node);
		return 0;
	}

	if (depth != 1)
		return 0;

	if (strcmp(uname, "rtas") == 0) {
		rtas_fadump_dt_scan(&fw_dump, node);
		return 1;
	}

	if (strcmp(uname, "ibm,opal") == 0) {
		opal_fadump_dt_scan(&fw_dump, node);
		return 1;
	}

	return 0;
}

/*
 * If fadump is registered, check if the memory provided
 * falls within boot memory area and reserved memory area.
 */
int is_fadump_memory_area(u64 addr, unsigned long size)
{
	u64 d_start, d_end;

	if (!fw_dump.dump_registered)
		return 0;

	if (!size)
		return 0;

	d_start = fw_dump.reserve_dump_area_start;
	d_end = d_start + fw_dump.reserve_dump_area_size;
	if (((addr + size) > d_start) && (addr <= d_end))
		return 1;

	return (addr <= fw_dump.boot_mem_top);
}

int should_fadump_crash(void)
{
	if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr)
		return 0;
	return 1;
}

int is_fadump_active(void)
{
	return fw_dump.dump_active;
}

/*
 * Returns true, if there are no holes in memory area between d_start to d_end,
 * false otherwise.
 */
static bool is_fadump_mem_area_contiguous(u64 d_start, u64 d_end)
{
	phys_addr_t reg_start, reg_end;
	bool ret = false;
	u64 i, start, end;

Annotation

Implementation Notes