arch/powerpc/platforms/powernv/opal-core.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/opal-core.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/powernv/opal-core.c
Extension
.c
Size
17317 bytes
Lines
655
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

struct opalcore_config {
	u32			num_cpus;
	/* PIR value of crashing CPU */
	u32			crashing_cpu;

	/* CPU state data info from F/W */
	u64			cpu_state_destination_vaddr;
	u64			cpu_state_data_size;
	u64			cpu_state_entry_size;

	/* OPAL memory to be exported as PT_LOAD segments */
	u64			ptload_addr[MAX_PT_LOAD_CNT];
	u64			ptload_size[MAX_PT_LOAD_CNT];
	u64			ptload_cnt;

	/* Pointer to the first PT_LOAD in the ELF core file */
	Elf64_Phdr		*ptload_phdr;

	/* Total size of opalcore file. */
	size_t			opalcore_size;

	/* Buffer for all the ELF core headers and the PT_NOTE */
	size_t			opalcorebuf_sz;
	char			*opalcorebuf;

	/* NT_AUXV buffer */
	char			auxv_buf[AUXV_DESC_SZ];
};

struct opalcore {
	struct list_head	list;
	u64			paddr;
	size_t			size;
	loff_t			offset;
};

static LIST_HEAD(opalcore_list);
static struct opalcore_config *oc_conf;
static const struct opal_mpipl_fadump *opalc_metadata;
static const struct opal_mpipl_fadump *opalc_cpu_metadata;
static struct kobject *mpipl_kobj;

/*
 * Set crashing CPU's signal to SIGUSR1. if the kernel is triggered
 * by kernel, SIGTERM otherwise.
 */
bool kernel_initiated;

static struct opalcore * __init get_new_element(void)
{
	return kzalloc_obj(struct opalcore);
}

static inline int is_opalcore_usable(void)
{
	return (oc_conf && oc_conf->opalcorebuf != NULL) ? 1 : 0;
}

static Elf64_Word *__init append_elf64_note(Elf64_Word *buf, char *name,
				     u32 type, void *data,
				     size_t data_len)
{
	Elf64_Nhdr *note = (Elf64_Nhdr *)buf;
	Elf64_Word namesz = strlen(name) + 1;

	note->n_namesz = cpu_to_be32(namesz);
	note->n_descsz = cpu_to_be32(data_len);
	note->n_type   = cpu_to_be32(type);
	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf64_Word));
	memcpy(buf, name, namesz);
	buf += DIV_ROUND_UP(namesz, sizeof(Elf64_Word));
	memcpy(buf, data, data_len);
	buf += DIV_ROUND_UP(data_len, sizeof(Elf64_Word));

	return buf;
}

static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
			  struct pt_regs *regs)
{
	memset(prstatus, 0, sizeof(struct elf_prstatus));
	elf_core_copy_regs(&(prstatus->pr_reg), regs);

	/*
	 * Overload PID with PIR value.
	 * As a PIR value could also be '0', add an offset of '100'
	 * to every PIR to avoid misinterpretations in GDB.
	 */
	prstatus->common.pr_pid  = cpu_to_be32(100 + pir);
	prstatus->common.pr_ppid = cpu_to_be32(1);

Annotation

Implementation Notes