arch/powerpc/platforms/pseries/rtas-fadump.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/pseries/rtas-fadump.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/pseries/rtas-fadump.c
Extension
.c
Size
20711 bytes
Lines
664
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source 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

switch (type) {
		case RTAS_FADUMP_CPU_STATE_DATA:
			addr = be64_to_cpu(fdm->rgn[i].destination_address);

			fadump_conf->cpu_state_dest_vaddr = (u64)__va(addr);
			/*
			 * Start address of reserve dump area (permanent reservation) for
			 * re-registering FADump after dump capture.
			 */
			fadump_conf->reserve_dump_area_start = addr;
			break;
		case RTAS_FADUMP_HPTE_REGION:
			/* Not processed currently. */
			break;
		case RTAS_FADUMP_REAL_MODE_REGION:
			base = be64_to_cpu(fdm->rgn[i].source_address);
			size = be64_to_cpu(fdm->rgn[i].source_len);
			pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);
			if (!base) {
				fadump_conf->boot_mem_dest_addr =
					be64_to_cpu(fdm->rgn[i].destination_address);
			}

			fadump_conf->boot_mem_addr[fadump_conf->boot_mem_regs_cnt] = base;
			fadump_conf->boot_mem_sz[fadump_conf->boot_mem_regs_cnt] = size;
			fadump_conf->boot_memory_size += size;
			hole_size += (base - last_end);
			last_end = base + size;
			fadump_conf->boot_mem_regs_cnt++;
			break;
		case RTAS_FADUMP_PARAM_AREA:
			fadump_conf->param_area = be64_to_cpu(fdm->rgn[i].destination_address);
			break;
		default:
			pr_warn("Section type %d unsupported on this kernel. Ignoring!\n", type);
			break;
		}
	}
	fadump_conf->boot_mem_top = fadump_conf->boot_memory_size + hole_size;

	rtas_fadump_update_config(fadump_conf, fdm);
}

static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
{
	u64 addr = fadump_conf->reserve_dump_area_start;
	u16 sec_cnt = 0;

	memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));
	addr = addr & PAGE_MASK;

	fdm.header.dump_format_version = cpu_to_be32(0x00000001);
	fdm.header.dump_status_flag = 0;
	fdm.header.offset_first_dump_section =
		cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct, rgn));

	/*
	 * Fields for disk dump option.
	 * We are not using disk dump option, hence set these fields to 0.
	 */
	fdm.header.dd_block_size = 0;
	fdm.header.dd_block_offset = 0;
	fdm.header.dd_num_blocks = 0;
	fdm.header.dd_offset_disk_path = 0;

	/* set 0 to disable an automatic dump-reboot. */
	fdm.header.max_time_auto = 0;

	/* Kernel dump sections */
	/* cpu state data section. */
	fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
	fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
	fdm.rgn[sec_cnt].source_address = 0;
	fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->cpu_state_data_size);
	fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
	addr += fadump_conf->cpu_state_data_size;
	sec_cnt++;

	/* hpte region section */
	fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
	fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
	fdm.rgn[sec_cnt].source_address = 0;
	fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->hpte_region_size);
	fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);
	addr += fadump_conf->hpte_region_size;
	sec_cnt++;

	/*
	 * Align boot memory area destination address to page boundary to
	 * be able to mmap read this area in the vmcore.

Annotation

Implementation Notes