@@ -1047,6 +1047,44 @@ static void dt_init_secureboot_node(const struct iplparams_sysparams *sysparams)
dt_add_property_cells(node, "hw-key-hash-size", hw_key_hash_size);
}
+/* Map architected register data to result-table */
+static int fadump_add_arch_regs(struct dt_node *dump_node,
+ struct fadump *result_table, int *res_table_cnt)
+{
+ const struct spira_ntuple *ntuple_proc_dump;
+ const struct proc_dump_area *arch_regs;
+ struct fadump_section *fadump_section;
+
+ ntuple_proc_dump = &spira.ntuples.proc_dump_area;
+ arch_regs = (void *)ntuple_proc_dump->addr;
+
+ if (arch_regs->dest_addr == 0 || arch_regs->act_size <= 0) {
+ prlog(PR_ERR,
+ "FADUMP: Architected register data is missing\n");
+ return OPAL_HARDWARE;
+ }
+
+ if (arch_regs->thread_size <= 0) {
+ prlog(PR_ERR,
+ "FADUMP: Invalid architected register thread size\n");
+ return OPAL_HARDWARE;
+ }
+
+ /* Add each thread size to device tree */
+ dt_add_property_cells(dump_node,
+ "cpu-data-size", arch_regs->thread_size);
+
+ fadump_section = &(result_table->section[*res_table_cnt]);
+ fadump_section->source_type = DUMP_REGION_CPU_DATA;
+ fadump_section->source_addr = arch_regs->dest_addr & ~(HRMOR_BIT);
+ fadump_section->dest_addr = arch_regs->dest_addr & ~(HRMOR_BIT);
+ fadump_section->source_size = arch_regs->act_size;
+ fadump_section->dest_size = arch_regs->act_size;
+ (*res_table_cnt)++;
+
+ return OPAL_SUCCESS;
+}
+
static void fadump_add_result_table(const struct iplparams_iplparams *p)
{
int i, j = 0;
@@ -1087,9 +1125,9 @@ static void fadump_add_result_table(const struct iplparams_iplparams *p)
prlog(PR_DEBUG, "FADUMP: Dump found, MDRT count = 0x%x\n", mdrt_cnt);
- /* Calculcate property size */
+ /* Number of entries in MDRT table + 1 for arch register data */
prop_size = sizeof(struct fadump) +
- (mdrt_cnt * sizeof(struct fadump_section));
+ ((mdrt_cnt + 1) * sizeof(struct fadump_section));
result_table = zalloc(prop_size);
if (!result_table) {
prlog(PR_ERR, "FADUMP: Failed to allocate memory\n");
@@ -1126,6 +1164,9 @@ static void fadump_add_result_table(const struct iplparams_iplparams *p)
return;
}
+ /* Add architected register data to result-table */
+ fadump_add_arch_regs(dump_node, result_table, &j);
+
result_table->section_count = j;
/* Actual property size */
prop_size = sizeof(struct fadump) + (j * sizeof(struct fadump_section));
@@ -1151,6 +1192,10 @@ static void fadump_add_node(void)
fw_load_area[2] = (u64)INITRAMFS_LOAD_BASE;
fw_load_area[3] = INITRAMFS_LOAD_SIZE;
dt_add_property(node, "fw-load-area", fw_load_area, sizeof(fw_load_area));
+
+ /* Architected register data format version */
+ dt_add_property_cells(node, "cpu-data-version",
+ PROC_DUMP_AREA_FORMAT_P9);
}
static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
Post MPIPL FSP/hostboot passes architected register data via HDAT. Add support to get architected register data from HDAT and pass it to kernel. Kernel will use this data to generate vmcore and opalcore. Device tree properties under /ibm,opal/dump node: cpu-data-version - Architected register data format version cpu-data-size - Per CPU register data size result-table - Add entry for architected register Based on cpu-data-size and result-table, kernel will be able to get data for indivisual CPU/register. Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> --- hdata/spira.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)