[Skiboot] [PATCH v2 12/17] hdata: Add architected register support
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Fri May 4 20:28:12 AEST 2018
Post MPIPL FSP/hostboot passes architected register data via HDAT. Add support
get architected register data from HDAT and pass it to kernel. Kernel will
use this data to generate vmcore and opalcore.
This patch moves 'proc_dump_area' ntuple from SPIRAH to SPIRAS..as HDAT provides
'proc_dump_area' under SPIRAS.
Device tree properties under /ibm,dump node:
cpu-data-version - Architected register data format version
cpu-data-size - Each 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 at linux.vnet.ibm.com>
---
hdata/spira.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
hdata/spira.h | 20 +++++++++++++++-----
2 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/hdata/spira.c b/hdata/spira.c
index 00bfa87a5..aa2733762 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -1121,6 +1121,47 @@ static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
dt_init_secureboot_node(p);
}
+/* Map architected register data from HDAT memory to result-table */
+static int fadump_add_arch_regs(struct dt_node *node,
+ struct fadump *result_table, int *res_cnt)
+{
+ u64 size, *addr;
+ const struct HDIF_common_hdr *reg_hdif;
+ const struct HDIF_array_hdr *reg_data;
+ struct fadump_section *fadump_section;
+
+ reg_hdif = get_hdif(&spira.ntuples.proc_dump_area, PROC_DUMP_HDIF_SIG);
+ if (!reg_hdif) {
+ prlog(PR_ERR, "FADUMP: Architected register is missing\n");
+ return OPAL_HARDWARE;
+ }
+
+ reg_data = HDIF_get_idata(reg_hdif, PROC_DUMP_ARCH_REG_DATA, NULL);
+ if (!CHECK_SPPTR(reg_data)) {
+ prlog(PR_ERR, "FADUMP: Invalid architected register data\n");
+ return OPAL_HARDWARE;
+ }
+
+ /* Add each thread size */
+ dt_add_property_cells(node, "cpu-data-size",
+ be32_to_cpu(reg_data->eactsz));
+ prlog(PR_TRACE, "FADUMP: Architected regs : thread count = %x, "
+ "size of each thread = %x\n",
+ be32_to_cpu(reg_data->ecnt), be32_to_cpu(reg_data->eactsz));
+
+ size = be32_to_cpu(reg_data->ecnt) * be32_to_cpu(reg_data->eactsz);
+ addr = (void *)reg_data + be32_to_cpu(reg_data->offset);
+
+ fadump_section = &(result_table->section[*res_cnt]);
+ fadump_section->source_type = DUMP_REGION_CPU_DATA;
+ fadump_section->source_addr = (u64)addr;
+ fadump_section->dest_addr = (u64)addr;
+ fadump_section->source_size = size;
+ fadump_section->dest_size = size;
+ (*res_cnt)++;
+ return OPAL_SUCCESS;
+}
+
static void fadump_add_result_table(struct dt_node *node,
const struct iplparams_iplparams *p)
{
@@ -1148,9 +1189,9 @@ static void fadump_add_result_table(struct dt_node *node,
prlog(PR_DEBUG, "FADUMP: Dump found, MDRT count = 0x%x\n", mdrt_cnt);
- /* Number of entries in MDRT table */
+ /* 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");
@@ -1187,6 +1228,9 @@ static void fadump_add_result_table(struct dt_node *node,
return;
}
+ /* Add architected register data to result-table */
+ fadump_add_arch_regs(node, result_table, &j);
+
result_table->section_count = j;
/* Actual property size */
prop_size = sizeof(struct fadump) + (j * sizeof(struct fadump_section));
@@ -1212,6 +1256,9 @@ static void fadump_add_node(const struct iplparams_iplparams *p)
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_ARCH_REG_VER);
+
fadump_add_result_table(node, p);
}
@@ -1801,6 +1848,7 @@ static void fixup_spira(void)
spira.ntuples.hs_data = spiras->ntuples.hs_data;
spira.ntuples.ipmi_sensor = spiras->ntuples.ipmi_sensor;
spira.ntuples.node_stb_data = spiras->ntuples.node_stb_data;
+ spira.ntuples.proc_dump_area = spiras->ntuples.proc_dump_area;
}
/*
diff --git a/hdata/spira.h b/hdata/spira.h
index 46d7c70c8..e0766fd49 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -76,6 +76,7 @@ struct spira_ntuples {
struct spira_ntuple hs_data; /* 0x320 */
struct spira_ntuple ipmi_sensor; /* 0x360 */
struct spira_ntuple node_stb_data; /* 0x380 */
+ struct spira_ntuple proc_dump_area; /* 0x3a0 */
};
struct spira {
@@ -89,7 +90,7 @@ struct spira {
*
* According to FSP engineers, this is an okay thing to do.
*/
- u8 reserved[0x80];
+ u8 reserved[0x40];
} __packed __align(0x100);
extern struct spira spira;
@@ -111,7 +112,6 @@ struct spirah_ntuples {
struct spira_ntuple mdump_src; /* 0x0a0 */
struct spira_ntuple mdump_dst; /* 0x0c0 */
struct spira_ntuple mdump_res; /* 0x0e0 */
- struct spira_ntuple proc_dump_area; /* 0x100 */
};
struct spirah {
@@ -119,7 +119,7 @@ struct spirah {
struct HDIF_idata_ptr ntuples_ptr;
__be64 pad;
struct spirah_ntuples ntuples;
- u8 reserved[0xE0];
+ u8 reserved[0x100];
} __packed __align(0x100);
extern struct spirah spirah;
@@ -132,7 +132,7 @@ extern struct spirah spirah;
#define SPIRAS_VERSION_P9 0x50
/* N-tuples in SPIRAS */
-#define SPIRAS_NTUPLES_COUNT 0x10
+#define SPIRAS_NTUPLES_COUNT 0x13
struct spiras_ntuples {
struct HDIF_array_hdr array_hdr; /* 0x030 */
@@ -154,6 +154,7 @@ struct spiras_ntuples {
struct spira_ntuple hbrt_data; /* 0x220 */
struct spira_ntuple ipmi_sensor; /* 0x240 */
struct spira_ntuple node_stb_data; /* 0x260 */
+ struct spira_ntuple proc_dump_area; /* 0x280 */
};
struct spiras {
@@ -161,7 +162,7 @@ struct spiras {
struct HDIF_idata_ptr ntuples_ptr;
__be64 pad;
struct spiras_ntuples ntuples;
- u8 reserved[0x180];
+ u8 reserved[0x160];
} __packed __align(0x100);
extern struct spiras *spiras;
@@ -1291,6 +1292,15 @@ struct hash_and_verification {
__be32 offset;
} __packed;
+
+/* Processor dump area. Used by MPIPL boot to get architected register data */
+#define PROC_DUMP_HDIF_SIG "ARCREG"
+
+/* Idata index 0 : Architected register data area */
+#define PROC_DUMP_ARCH_REG_DATA 0
+
+#define PROC_DUMP_ARCH_REG_VER 0x10 /* P9 format */
+
static inline const char *cpu_state(u32 flags)
{
switch ((flags & CPU_ID_VERIFY_MASK) >> CPU_ID_VERIFY_SHIFT) {
--
2.14.3
More information about the Skiboot
mailing list