diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-08-04 12:50:52 +0530 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-08-06 12:20:41 +0530 |
commit | d7ffcd939d971bdffc9e50bf7886345c9536d68c (patch) | |
tree | 44d6962df04920716926584bd093dda26e882466 /hdata | |
parent | c8c36ada1d9a07be1120663ab02dc87798362cb8 (diff) | |
download | skiboot-d7ffcd939d971bdffc9e50bf7886345c9536d68c.zip skiboot-d7ffcd939d971bdffc9e50bf7886345c9536d68c.tar.gz skiboot-d7ffcd939d971bdffc9e50bf7886345c9536d68c.tar.bz2 |
hdata: Add POWER10 support
Initial P10 support
- LPC : This contains two useful information:
LPC MCTP Memory Window Base Address
Second vUART console details
- Enable memory-buffer mmio
- Fix ipmi sensors
IPMI sensors are deprecated in P10. Hence do not parse ipmi sensors.
- I2C support
- Detect PHB5
- Create p10 xscom, xive, chiptod nodes
- Set pa-features bit for 2nd DAWR
Availability of 2nd DAWR depends on 0th bit of 64th byte of
ibm,pa-features property. Set it for p10.
Co-authored-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Co-authored-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Co-authored-by: Reza Arbab <arbab@linux.ibm.com>
Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
Co-authored-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hdata')
-rw-r--r-- | hdata/cpu-common.c | 19 | ||||
-rw-r--r-- | hdata/fsp.c | 10 | ||||
-rw-r--r-- | hdata/i2c.c | 5 | ||||
-rw-r--r-- | hdata/iohub.c | 50 | ||||
-rwxr-xr-x | hdata/memory.c | 8 | ||||
-rw-r--r-- | hdata/spira.c | 52 | ||||
-rw-r--r-- | hdata/spira.h | 20 | ||||
-rw-r--r-- | hdata/test/hdata_to_dt.c | 14 |
8 files changed, 148 insertions, 30 deletions
diff --git a/hdata/cpu-common.c b/hdata/cpu-common.c index e46f919..bf821c1 100644 --- a/hdata/cpu-common.c +++ b/hdata/cpu-common.c @@ -46,6 +46,18 @@ struct dt_node * add_core_common(struct dt_node *cpus, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 .. 55 */ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 56 .. 63 */ }; + const uint8_t pa_features_p10[] = { + 66, 0, + 0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xd0, 0x80, 0x00, /* 0 .. 7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 .. 15 */ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 16 .. 23 */ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 24 .. 31 */ + 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, /* 32 .. 39 */ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 40 .. 47 */ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 .. 55 */ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 56 .. 63 */ + 0x80, 0x00, /* 64 .. 65 */ + }; const uint8_t *pa_features; size_t pa_features_size; @@ -83,6 +95,11 @@ struct dt_node * add_core_common(struct dt_node *cpus, pa_features_size = sizeof(pa_features_p9); } break; + case PVR_TYPE_P10: + name = "PowerPC,POWER10"; + pa_features = pa_features_p10; + pa_features_size = sizeof(pa_features_p10); + break; default: name = "PowerPC,Unknown"; pa_features = NULL; @@ -103,7 +120,7 @@ struct dt_node * add_core_common(struct dt_node *cpus, dt_add_property_cells(cpu, "ibm,processor-page-sizes", 0xc, 0x10, 0x18, 0x22); - if (proc_gen == proc_gen_p9) + if (proc_gen >= proc_gen_p9) dt_add_property_cells(cpu, "ibm,processor-radix-AP-encodings", 0x0000000c, 0xa0000010, 0x20000015, 0x4000001e); diff --git a/hdata/fsp.c b/hdata/fsp.c index 18380e7..458b7e6 100644 --- a/hdata/fsp.c +++ b/hdata/fsp.c @@ -355,7 +355,7 @@ static void add_ipmi_sensors(struct dt_node *bmc_node) static void bmc_create_node(const struct HDIF_common_hdr *sp) { struct dt_node *bmc_node; - u32 fw_bar, io_bar, mem_bar, internal_bar; + u32 fw_bar, io_bar, mem_bar, internal_bar, mctp_base; const struct spss_iopath *iopath; const struct spss_sp_impl *sp_impl; struct dt_node *lpcm, *lpc, *n; @@ -370,7 +370,8 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp) dt_add_property_cells(bmc_node, "#size-cells", 0); /* Add sensor info under /bmc */ - add_ipmi_sensors(bmc_node); + if (proc_gen < proc_gen_p10) + add_ipmi_sensors(bmc_node); sp_impl = HDIF_get_idata(sp, SPSS_IDATA_SP_IMPL, &size); if (CHECK_SPPTR(sp_impl) && (size > 8)) { @@ -425,12 +426,17 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp) mem_bar = be32_to_cpu(iopath->lpc.memory_bar); io_bar = be32_to_cpu(iopath->lpc.io_bar); internal_bar = be32_to_cpu(iopath->lpc.internal_bar); + mctp_base = be32_to_cpu(iopath->lpc.mctp_base); prlog(PR_DEBUG, "LPC: IOPATH chip id = %x\n", chip_id); prlog(PR_DEBUG, "LPC: FW BAR = %#x\n", fw_bar); prlog(PR_DEBUG, "LPC: MEM BAR = %#x\n", mem_bar); prlog(PR_DEBUG, "LPC: IO BAR = %#x\n", io_bar); prlog(PR_DEBUG, "LPC: Internal BAR = %#x\n", internal_bar); + if (proc_gen >= proc_gen_p10) { + /* MCTP is part of FW BAR */ + prlog(PR_DEBUG, "LPC: MCTP base = %#x\n", mctp_base); + } /* * The internal address space BAR actually points to the LPC master diff --git a/hdata/i2c.c b/hdata/i2c.c index 8aa93d8..7d5d655 100644 --- a/hdata/i2c.c +++ b/hdata/i2c.c @@ -250,7 +250,7 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index, * This code makes a few assumptions about XSCOM addrs, etc * and will need updating for new processors */ - assert(proc_gen == proc_gen_p9); + assert(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10); /* * Emit an error if we get a newer version. This is an interim measure @@ -301,7 +301,8 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index, * engines outside this range so we don't create bogus * i2cm@<addr> nodes. */ - if (dev->i2cm_engine >= 4 && proc_gen == proc_gen_p9) + if (dev->i2cm_engine >= 4 && + (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10)) continue; bus = p8_i2c_add_port_node(xscom, dev->i2cm_engine, dev->i2cm_port, diff --git a/hdata/iohub.c b/hdata/iohub.c index fa3afbf..fb215e1 100644 --- a/hdata/iohub.c +++ b/hdata/iohub.c @@ -151,6 +151,7 @@ static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub, int phb_index, u8 active_phbs) { struct dt_node *stack; + const char *compat; u64 eq[8]; u8 *gen4; int i; @@ -158,9 +159,14 @@ static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub, stack = dt_new_addr(pbcq, "stack", stack_index); assert(stack); + if (proc_gen == proc_gen_p9) + compat = "ibm,power9-phb-stack"; + else + compat = "ibm,power10-phb-stack"; + dt_add_property_cells(stack, "reg", stack_index); dt_add_property_cells(stack, "ibm,phb-index", phb_index); - dt_add_property_string(stack, "compatible", "ibm,power9-phb-stack"); + dt_add_property_string(stack, "compatible", compat); /* XXX: This should probably just return if the PHB is disabled * rather than adding the extra properties. @@ -190,6 +196,7 @@ static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub, return stack; } +/* Add PHB4 on p9, PHB5 on p10 */ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub, const struct HDIF_common_hdr *sp_iohubs, struct dt_node *xcom, @@ -199,10 +206,21 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub, { struct dt_node *pbcq; uint8_t active_phb_mask = hub->fab_br0_pdt; - uint32_t pe_xscom = 0x4010c00 + (pec_index * 0x0000400); - uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000); + uint32_t pe_xscom; + uint32_t pci_xscom; + const char *compat; int i; + if (proc_gen == proc_gen_p9) { + pe_xscom = 0x4010c00 + (pec_index * 0x0000400); + pci_xscom = 0xd010800 + (pec_index * 0x1000000); + compat = "ibm,power9-pbcq"; + } else { + pe_xscom = 0x3011800 - (pec_index * 0x1000000); + pci_xscom = 0x8010800 + (pec_index * 0x1000000); + compat = "ibm,power10-pbcq"; + } + /* Create PBCQ node under xscom */ pbcq = dt_new_addr(xcom, "pbcq", pe_xscom); if (!pbcq) @@ -214,7 +232,7 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub, pci_xscom, 0x200); /* The hubs themselves go under the stacks */ - dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq"); + dt_add_property_strings(pbcq, "compatible", compat); dt_add_property_cells(pbcq, "ibm,pec-index", pec_index); dt_add_property_cells(pbcq, "#address-cells", 1); dt_add_property_cells(pbcq, "#size-cells", 0); @@ -229,7 +247,7 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub, */ io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code"); - prlog(PR_INFO, "CEC: Added PHB4 PBCQ %d with %d stacks\n", + prlog(PR_INFO, "CEC: Added PBCQ %d with %d stacks\n", pec_index, stacks); /* the actual PHB nodes created later on by skiboot */ @@ -267,6 +285,7 @@ static struct dt_node *io_add_p8(const struct cechub_io_hub *hub, return xscom; } +/* Add PBCQs for p9/p10 */ static struct dt_node *io_add_p9(const struct cechub_io_hub *hub, const struct HDIF_common_hdr *sp_iohubs) { @@ -280,17 +299,22 @@ static struct dt_node *io_add_p9(const struct cechub_io_hub *hub, xscom = find_xscom_for_chip(chip_id); if (!xscom) { - prerror("P9: Can't find XSCOM for chip %d\n", chip_id); + prerror("IOHUB: Can't find XSCOM for chip %d\n", chip_id); return NULL; } - prlog(PR_DEBUG, "IOHUB: PHB4 active bridge mask %x\n", + prlog(PR_DEBUG, "IOHUB: PHB active bridge mask %x\n", (u32) hub->fab_br0_pdt); /* Create PBCQs */ - io_add_phb4(hub, sp_iohubs, xscom, 0, 1, 0); - io_add_phb4(hub, sp_iohubs, xscom, 1, 2, 1); - io_add_phb4(hub, sp_iohubs, xscom, 2, 3, 3); + if (proc_gen == proc_gen_p9) { + io_add_phb4(hub, sp_iohubs, xscom, 0, 1, 0); + io_add_phb4(hub, sp_iohubs, xscom, 1, 2, 1); + io_add_phb4(hub, sp_iohubs, xscom, 2, 3, 3); + } else { /* p10 */ + io_add_phb4(hub, sp_iohubs, xscom, 0, 3, 0); + io_add_phb4(hub, sp_iohubs, xscom, 1, 3, 3); + } return xscom; } @@ -806,6 +830,10 @@ static void io_parse_fru(const void *sp_iohubs) prlog(PR_INFO, "CEC: Axone !\n"); io_add_p9(hub, sp_iohubs); break; + case CECHUB_HUB_RAINIER: + prlog(PR_INFO, "CEC: Rainier !\n"); + io_add_p9(hub, sp_iohubs); + break; default: prlog(PR_ERR, "CEC: Hub ID 0x%04x unsupported !\n", hub_id); @@ -817,7 +845,7 @@ static void io_parse_fru(const void *sp_iohubs) io_parse_slots(sp_iohubs, chip_id); } - if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9) + if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10) io_add_p8_cec_vpd(sp_iohubs); } diff --git a/hdata/memory.c b/hdata/memory.c index 6602add..efdb502 100755 --- a/hdata/memory.c +++ b/hdata/memory.c @@ -53,6 +53,8 @@ struct HDIF_ms_area_address_range { #define PHYS_ATTR_STATUS_SAVE_FAILED 0x02 #define PHYS_ATTR_STATUS_SAVED 0x04 #define PHYS_ATTR_STATUS_NOT_SAVED 0x08 +#define PHYS_ATTR_STATUS_ENCRYPTED 0x10 +#define PHYS_ATTR_STATUS_ERR_DETECTED 0x40 #define PHYS_ATTR_STATUS_MEM_INVALID 0xff /* Memory Controller ID for Nimbus P9 systems */ @@ -514,7 +516,7 @@ static void add_memory_buffer_mmio(const struct HDIF_common_hdr *msarea) struct dt_node *membuf; beint64_t *reg, *flags; - if (PVR_TYPE(mfspr(SPR_PVR)) != PVR_TYPE_P9P) + if (proc_gen <= proc_gen_p9 && PVR_TYPE(mfspr(SPR_PVR)) != PVR_TYPE_P9P) return; if (be16_to_cpu(msarea->version) < 0x50) { @@ -911,7 +913,8 @@ static bool __memory_parse(struct dt_node *root) prlog(PR_DEBUG, "MS VPD: is at %p\n", ms_vpd); msac = HDIF_get_idata(ms_vpd, MSVPD_IDATA_MS_ADDR_CONFIG, &size); - if (!CHECK_SPPTR(msac) || size < sizeof(*msac)) { + if (!CHECK_SPPTR(msac) || + size < offsetof(struct msvpd_ms_addr_config, max_possible_ms_address)) { prerror("MS VPD: bad msac size %u @ %p\n", size, msac); op_display(OP_FATAL, OP_MOD_MEM, 0x0002); return false; @@ -953,4 +956,3 @@ void memory_parse(void) abort(); } } - diff --git a/hdata/spira.c b/hdata/spira.c index 2e3b3a4..85c2fe7 100644 --- a/hdata/spira.c +++ b/hdata/spira.c @@ -301,6 +301,7 @@ static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id, addr = base | ((uint64_t)hw_id << PPC_BITLSHIFT(28)); break; case proc_gen_p9: + case proc_gen_p10: /* XXX P10 */ default: /* On P9 we need to put the chip ID in the natural powerbus * position. @@ -332,6 +333,10 @@ static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id, dt_add_property_strings(node, "compatible", "ibm,xscom", "ibm,power9-xscom"); break; + case proc_gen_p10: + dt_add_property_strings(node, "compatible", + "ibm,xscom", "ibm,power10-xscom"); + break; default: dt_add_property_strings(node, "compatible", "ibm,xscom"); } @@ -420,6 +425,11 @@ static void add_psihb_node(struct dt_node *np) psi_slen = 0x100; psi_comp = "ibm,power9-psihb-x"; break; + case proc_gen_p10: + psi_scom = 0x3011d00; + psi_slen = 0x100; + psi_comp = "ibm,power10-psihb-x"; + break; default: psi_comp = NULL; } @@ -438,10 +448,28 @@ static void add_psihb_node(struct dt_node *np) static void add_xive_node(struct dt_node *np) { - struct dt_node *xive = dt_new_addr(np, "xive", 0x5013000); + struct dt_node *xive; + const char *comp; + u32 scom, slen; + + switch (proc_gen) { + case proc_gen_p9: + scom = 0x5013000; + slen = 0x300; + comp = "ibm,power9-xive-x"; + break; + case proc_gen_p10: + scom = 0x2010800; + slen = 0x400; + comp = "ibm,power10-xive-x"; + break; + default: + return; + } - dt_add_property_cells(xive, "reg", 0x5013000, 0x300); - dt_add_property_string(xive, "compatible", "ibm,power9-xive-x"); + xive = dt_new_addr(np, "xive", scom); + dt_add_property_cells(xive, "reg", scom, slen); + dt_add_property_string(xive, "compatible", comp); /* HACK: required for simics */ dt_add_property(xive, "force-assign-bars", NULL, 0); @@ -725,6 +753,9 @@ static void add_chiptod_node(unsigned int chip_id, int flags) case proc_gen_p9: compat_str = "ibm,power9-chiptod"; break; + case proc_gen_p10: + compat_str = "ibm,power10-chiptod"; + break; default: return; } @@ -866,6 +897,7 @@ static void add_nx_node(u32 gcid) /* POWER9 NX is not software compatible with P8 NX */ dt_add_property_strings(nx, "compatible", "ibm,power9-nx"); break; + case proc_gen_p10: /* XXX P10 */ default: return; } @@ -903,15 +935,21 @@ static void add_nx(void) static void add_nmmu(void) { struct dt_node *xscom, *nmmu; + u32 scom; - /* Nest MMU only exists on POWER9 */ - if (proc_gen != proc_gen_p9) + /* Nest MMU only exists on POWER9 or later */ + if (proc_gen < proc_gen_p9) return; + if (proc_gen == proc_gen_p9) + scom = 0x5012c40; + else + scom = 0x2010c40; + dt_for_each_compatible(dt_root, xscom, "ibm,xscom") { - nmmu = dt_new_addr(xscom, "nmmu", 0x5012c40); + nmmu = dt_new_addr(xscom, "nmmu", scom); dt_add_property_strings(nmmu, "compatible", "ibm,power9-nest-mmu"); - dt_add_property_cells(nmmu, "reg", 0x5012c40, 0x20); + dt_add_property_cells(nmmu, "reg", scom, 0x20); } } diff --git a/hdata/spira.h b/hdata/spira.h index 18d73bd..7c5341f 100644 --- a/hdata/spira.h +++ b/hdata/spira.h @@ -304,7 +304,7 @@ struct spss_iopath { __be32 firmware_bar; __be32 internal_bar; - __be32 reserved2; + __be32 mctp_base; __be64 uart_base; __be32 uart_size; @@ -316,13 +316,27 @@ struct spss_iopath { #define UART_INT_LVL_LOW 0x1 #define UART_INT_RISING 0x2 #define UART_INT_LVL_HIGH 0x3 - uint8_t reserved3[2]; + uint8_t uart_valid; + uint8_t reserved3; __be64 bt_base; __be32 bt_size; uint8_t bt_sms_int_num; uint8_t bt_bmc_response_int_num; uint8_t reserved4[2]; + + __be16 kcs_data_reg_addr; + __be16 kcs_status_reg_addr; + uint8_t kcs_int_number; + + __be64 uart2_base; + __be32 uart2_size; + __be32 uart2_clk; /* UART baud clock in Hz */ + __be32 uart2_baud; /* UART baud rate */ + uint8_t uart2_int_number; + uint8_t uart2_int_type; + uint8_t uart2_valid; + uint8_t reserved5; } __packed lpc; }; } __packed; @@ -493,6 +507,7 @@ struct msvpd_ms_addr_config { __be64 max_possible_ms_address; __be32 deprecated; __be64 mirrorable_memory_starting_address; + __be64 hrmor_stash_loc_address; } __packed; /* Idata index 1: Total configured mainstore */ @@ -651,6 +666,7 @@ struct cechub_io_hub { #define CECHUB_HUB_NIMBUS_LAGRANGE 0x0022 /* Nimbus+lagrange from spec */ #define CECHUB_HUB_CUMULUS_DUOMO 0x0030 /* cumulus+duomo from spec */ #define CECHUB_HUB_AXONE_HOPPER 0x0040 /* axone+hopper */ +#define CECHUB_HUB_RAINIER 0x0050 __be32 ec_level; __be32 aff_dom2; /* HDAT < v9.x only */ __be32 aff_dom3; /* HDAT < v9.x only */ diff --git a/hdata/test/hdata_to_dt.c b/hdata/test/hdata_to_dt.c index 90d83f9..1729f1c 100644 --- a/hdata/test/hdata_to_dt.c +++ b/hdata/test/hdata_to_dt.c @@ -2,7 +2,7 @@ /* * Given a hdata dump, output the device tree. * - * Copyright 2013-2019 IBM Corp. + * Copyright 2013-2020 IBM Corp. */ #include <sys/types.h> @@ -63,11 +63,13 @@ unsigned long tb_hz = 512000000; #define PVR_TYPE_P8NVL 0x004c #define PVR_TYPE_P9 0x004e #define PVR_TYPE_P9P 0x004f +#define PVR_TYPE_P10 0x0080 #define PVR_P8E 0x004b0201 #define PVR_P8 0x004d0200 #define PVR_P8NVL 0x004c0100 #define PVR_P9 0x004e0200 #define PVR_P9P 0x004f0100 +#define PVR_P10 0x00800100 #define SPR_PVR 0x11f /* RO: Processor version register */ @@ -328,6 +330,10 @@ int main(int argc, char *argv[]) fake_pvr = PVR_P9P; proc_gen = proc_gen_p9; opt_count++; + } else if (strcmp(argv[i], "-10") == 0) { + fake_pvr = PVR_P10; + proc_gen = proc_gen_p10; + opt_count++; } } @@ -347,13 +353,17 @@ int main(int argc, char *argv[]) " -8 Force PVR to POWER8\n" " -8E Force PVR to POWER8E\n" " -9 Force PVR to POWER9 (nimbus)\n" + " -9P Force PVR to POWER9P (Axone)\n" + " -10 Force PVR to POWER10\n" "\n" "When no PVR is specified -8 is assumed" "\n" "Pipe to 'dtc -I dtb -O dts' for human readable output\n"); } - phys_map_init(fake_pvr); + /* We don't have phys mapping for P8 */ + if (proc_gen != proc_gen_p8) + phys_map_init(fake_pvr); /* Copy in spira dump (assumes little has changed!). */ if (new_spira) { |