From mahesh at linux.ibm.com Thu Apr 4 16:56:15 2024 From: mahesh at linux.ibm.com (Mahesh Salgaonkar) Date: Thu, 4 Apr 2024 11:26:15 +0530 Subject: [Skiboot] [PATCH 1/4] Initial Power11 enablement Message-ID: <20240404055618.1439108-1-mahesh@linux.ibm.com> Detect Power11 PVR and use P10 code path. Signed-off-by: Mahesh Salgaonkar --- asm/head.S | 12 +++++++++--- asm/misc.S | 4 +++- core/affinity.c | 2 ++ core/chip.c | 23 ++++++++++++++++++++--- core/cpu.c | 18 +++++++++++++++++- core/direct-controls.c | 18 +++++++++--------- core/fast-reboot.c | 4 ++-- core/hmi.c | 12 ++++++++---- core/init.c | 10 +++++----- core/mce.c | 2 ++ hdata/i2c.c | 5 +++-- hdata/iohub.c | 3 ++- hdata/spira.c | 15 +++++++++++++-- hw/chiptod.c | 2 +- hw/fsp/fsp-occ.c | 1 + hw/fsp/fsp-psi.c | 1 + hw/homer.c | 1 + hw/imc.c | 5 ++++- hw/lpc.c | 7 +++++-- hw/occ.c | 4 +++- hw/p8-i2c.c | 2 +- hw/phb4.c | 2 +- hw/phys-map.c | 3 +++ hw/prd.c | 1 + hw/psi.c | 8 +++++++- hw/sbe.c | 2 +- hw/slw.c | 7 ++++--- hw/vas.c | 2 +- hw/xive2.c | 4 ++-- hw/xscom.c | 13 +++++++++---- include/chip.h | 1 + include/phb4.h | 2 +- include/processor.h | 6 ++++++ include/skiboot.h | 1 + platforms/ibm-fsp/hostservices.c | 1 + 35 files changed, 151 insertions(+), 53 deletions(-) diff --git a/asm/head.S b/asm/head.S index bf2a66ee30..5de3483004 100644 --- a/asm/head.S +++ b/asm/head.S @@ -324,7 +324,7 @@ boot_offset: * r28 : PVR * r27 : DTB pointer (or NULL) * r26 : PIR thread mask - * r25 : P9/10 fused core flag + * r25 : P9/10/11 fused core flag */ .global boot_entry boot_entry: @@ -344,6 +344,8 @@ boot_entry: beq 3f cmpwi cr0,%r3,PVR_TYPE_P10 beq 4f + cmpwi cr0,%r3,PVR_TYPE_P11 + beq 4f attn /* Unsupported CPU type... what do we do ? */ b . /* loop here, just in case attn is disabled */ @@ -357,7 +359,7 @@ boot_entry: b 2f 4: /* - * P10 fused core check (SPRC/SPRD method does not work). + * P10/11 fused core check (SPRC/SPRD method does not work). * PVR bit 12 set = normal code */ andi. %r3, %r28, 0x1000 @@ -743,6 +745,8 @@ init_shared_sprs: beq 4f cmpwi cr0,%r3,PVR_TYPE_P10 beq 5f + cmpwi cr0,%r3,PVR_TYPE_P11 + beq 5f /* Unsupported CPU type... what do we do ? */ b 9f @@ -868,6 +872,8 @@ init_replicated_sprs: beq 4f cmpwi cr0,%r3,PVR_TYPE_P10 beq 5f + cmpwi cr0,%r3,PVR_TYPE_P11 + beq 5f /* Unsupported CPU type... what do we do ? */ b 9f @@ -891,7 +897,7 @@ init_replicated_sprs: LOAD_IMM64(%r3,0x0000000000000010) mtspr SPR_DSCR,%r3 -5: /* P10 */ +5: /* P10/11 */ /* LPCR: sane value */ LOAD_IMM64(%r3,0x0040000000000000) mtspr SPR_LPCR, %r3 diff --git a/asm/misc.S b/asm/misc.S index ea43763228..8c2ed6f6ec 100644 --- a/asm/misc.S +++ b/asm/misc.S @@ -99,7 +99,7 @@ cleanup_local_tlb: .global cleanup_global_tlb cleanup_global_tlb: - /* Only supported on P9, P10 for now */ + /* Only supported on P9, P10, P11 for now */ mfspr %r3,SPR_PVR srdi %r3,%r3,16 cmpwi cr0,%r3,PVR_TYPE_P9 @@ -108,6 +108,8 @@ cleanup_global_tlb: beq cr0,1f cmpwi cr0,%r3,PVR_TYPE_P10 beq cr0,1f + cmpwi cr0,%r3,PVR_TYPE_P11 + beq cr0,1f blr /* Sync out previous updates */ diff --git a/core/affinity.c b/core/affinity.c index 0209d3cd9e..1dd9b4c331 100644 --- a/core/affinity.c +++ b/core/affinity.c @@ -113,6 +113,8 @@ void add_core_associativity(struct cpu_thread *cpu) core_id = (cpu->pir >> 2) & 0x1f; else if (proc_gen == proc_gen_p10) core_id = (cpu->pir >> 2) & 0x1f; + else if (proc_gen == proc_gen_p11) + core_id = (cpu->pir >> 2) & 0x1f; else return; diff --git a/core/chip.c b/core/chip.c index 0e96e62537..2576e27a34 100644 --- a/core/chip.c +++ b/core/chip.c @@ -13,7 +13,9 @@ enum proc_chip_quirks proc_chip_quirks; uint32_t pir_to_chip_id(uint32_t pir) { - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p11) + return P10_PIR2GCID(pir); + else if (proc_gen == proc_gen_p10) return P10_PIR2GCID(pir); else if (proc_gen == proc_gen_p9) return P9_PIR2GCID(pir); @@ -25,7 +27,12 @@ uint32_t pir_to_chip_id(uint32_t pir) uint32_t pir_to_core_id(uint32_t pir) { - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p11) { + if (this_cpu()->is_fused_core) + return P10_PIRFUSED2NORMALCOREID(pir); + else + return P10_PIR2COREID(pir); + } else if (proc_gen == proc_gen_p10) { if (this_cpu()->is_fused_core) return P10_PIRFUSED2NORMALCOREID(pir); else @@ -44,7 +51,12 @@ uint32_t pir_to_core_id(uint32_t pir) uint32_t pir_to_fused_core_id(uint32_t pir) { - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p11) { + if (this_cpu()->is_fused_core) + return P10_PIR2FUSEDCOREID(pir); + else + return P10_PIR2COREID(pir); + } else if (proc_gen == proc_gen_p10) { if (this_cpu()->is_fused_core) return P10_PIR2FUSEDCOREID(pir); else @@ -68,6 +80,11 @@ uint32_t pir_to_thread_id(uint32_t pir) return P10_PIRFUSED2NORMALTHREADID(pir); else return P10_PIR2THREADID(pir); + } else if (proc_gen == proc_gen_p10) { + if (this_cpu()->is_fused_core) + return P10_PIRFUSED2NORMALTHREADID(pir); + else + return P10_PIR2THREADID(pir); } else if (proc_gen == proc_gen_p9) { if (this_cpu()->is_fused_core) return P9_PIRFUSED2NORMALTHREADID(pir); diff --git a/core/cpu.c b/core/cpu.c index 48ee1a5cd6..3e3547225a 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -102,7 +102,8 @@ static void cpu_send_ipi(struct cpu_thread *cpu) if (proc_gen == proc_gen_p8) { /* Poke IPI */ icp_kick_cpu(cpu); - } else if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10) { + } else if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || + proc_gen == proc_gen_p11) { p9_dbell_send(cpu->pir); } } @@ -1056,6 +1057,13 @@ void init_boot_cpu(void) hid0_attn = SPR_HID0_POWER10_ENABLE_ATTN; hid0_icache = SPR_HID0_POWER10_FLUSH_ICACHE; break; + case PVR_TYPE_P11: + proc_gen = proc_gen_p11; + radix_supported = true; + hid0_hile = SPR_HID0_POWER10_HILE; + hid0_attn = SPR_HID0_POWER10_ENABLE_ATTN; + hid0_icache = SPR_HID0_POWER10_FLUSH_ICACHE; + break; default: proc_gen = proc_gen_unknown; } @@ -1083,6 +1091,14 @@ void init_boot_cpu(void) prlog(PR_INFO, "CPU: P10 generation processor" " (max %d threads/core)\n", cpu_thread_count); break; + case proc_gen_p11: + if (is_fused_core(pvr)) + cpu_thread_count = 8; + else + cpu_thread_count = 4; + prlog(PR_INFO, "CPU: Power11 generation processor" + " (max %d threads/core)\n", cpu_thread_count); + break; default: prerror("CPU: Unknown PVR, assuming 1 thread\n"); cpu_thread_count = 1; diff --git a/core/direct-controls.c b/core/direct-controls.c index 37bcf9826f..9dd9b15476 100644 --- a/core/direct-controls.c +++ b/core/direct-controls.c @@ -861,7 +861,7 @@ int dctl_set_special_wakeup(struct cpu_thread *t) lock(&c->dctl_lock); if (c->special_wakeup_count == 0) { - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) rc = p10_core_set_special_wakeup(c); else if (proc_gen == proc_gen_p9) rc = p9_core_set_special_wakeup(c); @@ -887,7 +887,7 @@ int dctl_clear_special_wakeup(struct cpu_thread *t) if (!c->special_wakeup_count) goto out; if (c->special_wakeup_count == 1) { - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) rc = p10_core_clear_special_wakeup(c); else if (proc_gen == proc_gen_p9) rc = p9_core_clear_special_wakeup(c); @@ -906,7 +906,7 @@ int dctl_core_is_gated(struct cpu_thread *t) { struct cpu_thread *c = t->primary; - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) return p10_core_is_gated(c); else if (proc_gen == proc_gen_p9) return p9_core_is_gated(c); @@ -924,7 +924,7 @@ static int dctl_stop(struct cpu_thread *t) unlock(&c->dctl_lock); return OPAL_BUSY; } - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) rc = p10_stop_thread(t); else if (proc_gen == proc_gen_p9) rc = p9_stop_thread(t); @@ -942,7 +942,7 @@ static int dctl_cont(struct cpu_thread *t) struct cpu_thread *c = t->primary; int rc; - if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p9) + if (proc_gen != proc_gen_p11 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p9) return OPAL_UNSUPPORTED; lock(&c->dctl_lock); @@ -950,7 +950,7 @@ static int dctl_cont(struct cpu_thread *t) unlock(&c->dctl_lock); return OPAL_BUSY; } - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) rc = p10_cont_thread(t); else /* (proc_gen == proc_gen_p9) */ rc = p9_cont_thread(t); @@ -977,7 +977,7 @@ static int dctl_sreset(struct cpu_thread *t) unlock(&c->dctl_lock); return OPAL_BUSY; } - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) rc = p10_sreset_thread(t); else if (proc_gen == proc_gen_p9) rc = p9_sreset_thread(t); @@ -1124,7 +1124,7 @@ int64_t opal_signal_system_reset(int cpu_nr) struct cpu_thread *cpu; int64_t ret; - if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10) + if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11) return OPAL_UNSUPPORTED; /* @@ -1154,7 +1154,7 @@ void direct_controls_init(void) if (chip_quirk(QUIRK_MAMBO_CALLOUTS)) return; - if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10) + if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11) return; opal_register(OPAL_SIGNAL_SYSTEM_RESET, opal_signal_system_reset, 1); diff --git a/core/fast-reboot.c b/core/fast-reboot.c index 6f6ef3ae2d..fdbcdf72a2 100644 --- a/core/fast-reboot.c +++ b/core/fast-reboot.c @@ -263,7 +263,7 @@ static void cleanup_cpu_state(void) if (proc_gen == proc_gen_p9) xive_cpu_reset(); - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) xive2_cpu_reset(); /* Per core cleanup */ @@ -388,7 +388,7 @@ void __noreturn fast_reboot_entry(void) if (proc_gen == proc_gen_p9) xive_reset(); - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) xive2_reset(); /* Let the CPU layer do some last minute global cleanups */ diff --git a/core/hmi.c b/core/hmi.c index 7f4211c5d1..0abf302c83 100644 --- a/core/hmi.c +++ b/core/hmi.c @@ -404,6 +404,7 @@ static int setup_scom_addresses(void) nx_pbi_fir = P9_NX_PBI_FIR; return 1; case proc_gen_p10: + case proc_gen_p11: malf_alert_scom = P10_MALFUNC_ALERT; nx_status_reg = P10_NX_STATUS_REG; nx_dma_engine_fir = P10_NX_DMA_ENGINE_FIR; @@ -460,6 +461,7 @@ static int read_core_fir(uint32_t chip_id, uint32_t core_id, uint64_t *core_fir) XSCOM_ADDR_P9_EC(core_id, P9_CORE_FIR), core_fir); break; case proc_gen_p10: + case proc_gen_p11: rc = xscom_read(chip_id, XSCOM_ADDR_P10_EC(core_id, P10_CORE_FIR), core_fir); break; @@ -479,6 +481,7 @@ static int read_core_wof(uint32_t chip_id, uint32_t core_id, uint64_t *core_wof) XSCOM_ADDR_P9_EC(core_id, P9_CORE_WOF), core_wof); break; case proc_gen_p10: + case proc_gen_p11: rc = xscom_read(chip_id, XSCOM_ADDR_P10_EC(core_id, P10_CORE_WOF), core_wof); break; @@ -541,7 +544,7 @@ static bool decode_core_fir(struct cpu_thread *cpu, loc ? loc : "Not Available", cpu->chip_id, core_id, core_fir); - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { for (i = 0; i < ARRAY_SIZE(p10_core_fir_bits); i++) { if (core_fir & PPC_BIT(p10_core_fir_bits[i].bit)) prlog(PR_INFO, " %s\n", p10_core_fir_bits[i].reason); @@ -949,7 +952,7 @@ static void decode_malfunction(struct OpalHMIEvent *hmi_evt, uint64_t *out_flags xscom_write(this_cpu()->chip_id, malf_alert_scom, ~PPC_BIT(i)); find_capp_checkstop_reason(i, hmi_evt, &flags); - if (proc_gen != proc_gen_p10) + if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11) find_nx_checkstop_reason(i, hmi_evt, &flags); find_npu_checkstop_reason(i, hmi_evt, &flags); } @@ -1413,7 +1416,7 @@ static int handle_hmi_exception(uint64_t hmer, struct OpalHMIEvent *hmi_evt, if (core_wof & PPC_BIT(p9_recoverable_bits[i].bit)) prlog(PR_DEBUG, " %s\n", p9_recoverable_bits[i].reason); } - } else if (proc_gen == proc_gen_p10) { + } else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { for (i = 0; i < ARRAY_SIZE(p10_core_fir_bits); i++) { if (core_wof & PPC_BIT(p10_core_fir_bits[i].bit)) prlog(PR_DEBUG, " %s\n", p10_core_fir_bits[i].reason); @@ -1508,7 +1511,8 @@ static int handle_hmi_exception(uint64_t hmer, struct OpalHMIEvent *hmi_evt, queue_hmi_event(hmi_evt, recover, out_flags); } } - if ((proc_gen == proc_gen_p10) && (hmer & SPR_HMER_P10_TRIG_FIR_HMI)) { + if ((proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) + && (hmer & SPR_HMER_P10_TRIG_FIR_HMI)) { handled |= SPR_HMER_P10_TRIG_FIR_HMI; hmer &= ~SPR_HMER_P10_TRIG_FIR_HMI; diff --git a/core/init.c b/core/init.c index 2d8a54595e..8e49bb966a 100644 --- a/core/init.c +++ b/core/init.c @@ -1005,7 +1005,7 @@ static void mask_pc_system_xstop(void) uint32_t chip_id, core_id; int rc; - if (proc_gen != proc_gen_p10) + if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11) return; if (chip_quirk(QUIRK_MAMBO_CALLOUTS) || chip_quirk(QUIRK_AWAN)) @@ -1046,7 +1046,7 @@ static void probe_lpar_per_core(void) if (proc_gen == proc_gen_p9) addr = XSCOM_ADDR_P9_EC(core_id, P9_CORE_THREAD_STATE); - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) addr = XSCOM_ADDR_P10_EC(core_id, P10_EC_CORE_THREAD_STATE); else return; @@ -1243,7 +1243,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) /* Initialize the rest of the cpu thread structs */ init_all_cpus(); - if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) cpu_set_ipi_enable(true); /* Once all CPU are up apply this workaround */ @@ -1274,7 +1274,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt) /* On P9 and P10, initialize XIVE */ if (proc_gen == proc_gen_p9) init_xive(); - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) xive2_init(); /* Grab centaurs from device-tree if present (only on FSP-less) */ @@ -1483,7 +1483,7 @@ void __noreturn __secondary_cpu_entry(void) /* Some XIVE setup */ if (proc_gen == proc_gen_p9) xive_cpu_callin(cpu); - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) xive2_cpu_callin(cpu); /* Wait for work to do */ diff --git a/core/mce.c b/core/mce.c index 47674abcb2..f21db1fdd7 100644 --- a/core/mce.c +++ b/core/mce.c @@ -303,6 +303,8 @@ void decode_mce(uint64_t srr0, uint64_t srr1, decode_mce_p9(srr0, srr1, dsisr, dar, type, error_str, address); } else if (proc_gen == proc_gen_p10) { decode_mce_p10(srr0, srr1, dsisr, dar, type, error_str, address); + } else if (proc_gen == proc_gen_p11) { + decode_mce_p10(srr0, srr1, dsisr, dar, type, error_str, address); } else { *error_str = "unknown error (processor not supported)"; } diff --git a/hdata/i2c.c b/hdata/i2c.c index 7d5d655a53..d62cfa080b 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 || proc_gen == proc_gen_p10); + assert(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11); /* * Emit an error if we get a newer version. This is an interim measure @@ -302,7 +302,8 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index, * i2cm@ nodes. */ if (dev->i2cm_engine >= 4 && - (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10)) + (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || + proc_gen == proc_gen_p11)) 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 d1074241b6..40712bc94d 100644 --- a/hdata/iohub.c +++ b/hdata/iohub.c @@ -858,7 +858,8 @@ 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 || proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 + || proc_gen == proc_gen_p11) io_add_p8_cec_vpd(sp_iohubs); } diff --git a/hdata/spira.c b/hdata/spira.c index d9325a0b44..b008df66ce 100644 --- a/hdata/spira.c +++ b/hdata/spira.c @@ -277,6 +277,7 @@ static struct dt_node *add_xscom_node(uint64_t base, addr = base | (((uint64_t)hw_id) << 42); break; case proc_gen_p10: + case proc_gen_p11: default: /* Use Primary topology table index for xscom address */ addr = base | (((uint64_t)cinfo->topology_id_table[cinfo->primary_topology_loc]) << 44); @@ -310,6 +311,10 @@ static struct dt_node *add_xscom_node(uint64_t base, dt_add_property_strings(node, "compatible", "ibm,xscom", "ibm,power10-xscom"); break; + case proc_gen_p11: + dt_add_property_strings(node, "compatible", + "ibm,xscom", "ibm,power11-xscom"); + break; default: dt_add_property_strings(node, "compatible", "ibm,xscom"); } @@ -399,6 +404,7 @@ static void add_psihb_node(struct dt_node *np) psi_comp = "ibm,power9-psihb-x"; break; case proc_gen_p10: + case proc_gen_p11: psi_scom = 0x3011d00; psi_slen = 0x100; psi_comp = "ibm,power10-psihb-x"; @@ -432,6 +438,7 @@ static void add_xive_node(struct dt_node *np) comp = "ibm,power9-xive-x"; break; case proc_gen_p10: + case proc_gen_p11: scom = 0x2010800; slen = 0x400; comp = "ibm,power10-xive-x"; @@ -745,6 +752,9 @@ static void add_chiptod_node(unsigned int chip_id, int flags) case proc_gen_p10: compat_str = "ibm,power10-chiptod"; break; + case proc_gen_p11: + compat_str = "ibm,power11-chiptod"; + break; default: return; } @@ -856,6 +866,7 @@ static void add_nx_node(u32 gcid) break; case proc_gen_p9: case proc_gen_p10: + case proc_gen_p11: /* POWER9 NX is not software compatible with P8 NX */ dt_add_property_strings(nx, "compatible", "ibm,power9-nx"); break; @@ -903,7 +914,7 @@ static void add_nmmu(void) if (proc_gen < proc_gen_p9) return; - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { scom1 = 0x2010c40; scom2 = 0x3010c40; } else @@ -918,7 +929,7 @@ static void add_nmmu(void) * P10 has a second nMMU, a.k.a "south" nMMU. * It exists only on P1 and P3 */ - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { chip_id = __dt_get_chip_id(xscom); if (chip_id != 2 && chip_id != 6) diff --git a/hw/chiptod.c b/hw/chiptod.c index e3941e296d..e2f0d7c1d9 100644 --- a/hw/chiptod.c +++ b/hw/chiptod.c @@ -1026,7 +1026,7 @@ static void fixup_tod_reg_value(struct chiptod_tod_regs *treg_entry) { int32_t chip_id = this_cpu()->chip_id; - if (proc_gen != proc_gen_p10) + if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11) return; if (treg_entry->xscom_addr == TOD_SLAVE_PATH_CTRL) diff --git a/hw/fsp/fsp-occ.c b/hw/fsp/fsp-occ.c index 58926f4088..a0fe57bff9 100644 --- a/hw/fsp/fsp-occ.c +++ b/hw/fsp/fsp-occ.c @@ -317,6 +317,7 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) break; case proc_gen_p9: case proc_gen_p10: + case proc_gen_p11: last_seq_id = seq_id; chip = next_chip(NULL); prd_fsp_occ_reset(chip->id); diff --git a/hw/fsp/fsp-psi.c b/hw/fsp/fsp-psi.c index 38f130dd79..ce37ca53d1 100644 --- a/hw/fsp/fsp-psi.c +++ b/hw/fsp/fsp-psi.c @@ -38,6 +38,7 @@ void psi_init_for_fsp(struct psi *psi) case proc_gen_p8: case proc_gen_p9: case proc_gen_p10: + case proc_gen_p11: out_be64(psi->regs + PSIHB_TAR, PSI_TCE_TABLE_BASE | PSIHB_TAR_256K_ENTRIES); break; diff --git a/hw/homer.c b/hw/homer.c index 3ff6ed1ae9..fc5f4fb490 100644 --- a/hw/homer.c +++ b/hw/homer.c @@ -201,6 +201,7 @@ void homer_init(void) bar_occ_common = P9_BAR_OCC_COMMON; break; case proc_gen_p10: + case proc_gen_p11: pba_bar0 = P10_PBA_BAR0; pba_barmask0 = P10_PBA_BARMASK0; bar_homer = P10_BAR_HOMER; diff --git a/hw/imc.c b/hw/imc.c index a794cc28f6..4ab2b51b06 100644 --- a/hw/imc.c +++ b/hw/imc.c @@ -481,7 +481,7 @@ static void disable_unavailable_units(struct dt_node *dev) dt_free(target); } } - } else if (proc_gen == proc_gen_p10) { + } else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { int val; char name[8]; @@ -761,6 +761,7 @@ static int setup_imc_scoms(void) IMC_TRACE_BUFF_SIZE); return 0; case proc_gen_p10: + case proc_gen_p11: CORE_IMC_EVENT_MASK_ADDR = CORE_IMC_EVENT_MASK_ADDR_P10; TRACE_IMC_ADDR = TRACE_IMC_ADDR_P10; pdbar_scom_index = pdbar_scom_index_p10; @@ -933,6 +934,7 @@ static uint32_t get_imc_scom_addr_for_core(int core, uint64_t addr) scom_addr = XSCOM_ADDR_P9_EC(core, addr); return scom_addr; case proc_gen_p10: + case proc_gen_p11: scom_addr = XSCOM_ADDR_P10_EC(core, addr); return scom_addr; default: @@ -950,6 +952,7 @@ static uint32_t get_imc_scom_addr_for_quad(int core, uint64_t addr) scom_addr = XSCOM_ADDR_P9_EQ(core, addr); return scom_addr; case proc_gen_p10: + case proc_gen_p11: scom_addr = XSCOM_ADDR_P10_EQ(core, addr); return scom_addr; default: diff --git a/hw/lpc.c b/hw/lpc.c index caaacc4610..114cc1258e 100644 --- a/hw/lpc.c +++ b/hw/lpc.c @@ -990,7 +990,8 @@ void lpc_finalize_interrupts(void) (chip->type == PROC_CHIP_P9_NIMBUS || chip->type == PROC_CHIP_P9_CUMULUS || chip->type == PROC_CHIP_P9P || - chip->type == PROC_CHIP_P10)) + chip->type == PROC_CHIP_P10 || + chip->type == PROC_CHIP_P11)) lpc_create_int_map(chip->lpc, chip->psi->node); } } @@ -1035,6 +1036,7 @@ static void lpc_init_interrupts_one(struct proc_chip *chip) case PROC_CHIP_P9_CUMULUS: case PROC_CHIP_P9P: case PROC_CHIP_P10: + case PROC_CHIP_P11: /* On P9, we additionally setup the routing. */ lpc->has_serirq = true; for (i = 0; i < LPC_NUM_SERIRQ; i++) { @@ -1454,7 +1456,8 @@ void lpc_register_client(uint32_t chip_id, chip->type == PROC_CHIP_P9_NIMBUS || chip->type == PROC_CHIP_P9_CUMULUS || chip->type == PROC_CHIP_P9P || - chip->type == PROC_CHIP_P10; + chip->type == PROC_CHIP_P10 || + chip->type == PROC_CHIP_P11; if (policy != IRQ_ATTR_TARGET_OPAL && !has_routes) { prerror("Chip doesn't support OS interrupt policy\n"); diff --git a/hw/occ.c b/hw/occ.c index 8d7bcbec93..c011d52f0f 100644 --- a/hw/occ.c +++ b/hw/occ.c @@ -2021,6 +2021,7 @@ void occ_pstates_init(void) break; case proc_gen_p9: case proc_gen_p10: + case proc_gen_p11: homer_opal_data_offset = P9_HOMER_OPAL_DATA_OFFSET; break; default: @@ -2083,7 +2084,7 @@ void occ_pstates_init(void) } else if (proc_gen == proc_gen_p9) { freq_domain_mask = P9_PIR_QUAD_MASK; domain_runs_at = FREQ_MAX_IN_DOMAIN; - } else if (proc_gen == proc_gen_p10) { + } else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { freq_domain_mask = P10_PIR_CHIP_MASK; domain_runs_at = FREQ_MAX_IN_DOMAIN; } else { @@ -2258,6 +2259,7 @@ void occ_send_dummy_interrupt(void) OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY); break; case proc_gen_p10: + case proc_gen_p11: xscom_write(psi->chip_id, P9_OCB_OCI_OCCMISC_OR, OCB_OCI_OCIMISC_IRQ | OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY); diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c index 45815858e9..4b534f68b5 100644 --- a/hw/p8-i2c.c +++ b/hw/p8-i2c.c @@ -1587,7 +1587,7 @@ void p8_i2c_init(void) /* setup the handshake reg */ if (proc_gen <= proc_gen_p9) occflg = 0x6C08A; - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) occflg = 0x6C0AC; else return; diff --git a/hw/phb4.c b/hw/phb4.c index b1fa08fe1c..45304e7acd 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -147,7 +147,7 @@ static inline bool is_phb4(void) static inline bool is_phb5(void) { - return (proc_gen == proc_gen_p10); + return (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11); } /* PQ offloading on the XIVE IC. */ diff --git a/hw/phys-map.c b/hw/phys-map.c index cfce4ab529..196a222c35 100644 --- a/hw/phys-map.c +++ b/hw/phys-map.c @@ -486,6 +486,9 @@ void phys_map_init(unsigned long pvr) } else if (proc_gen == proc_gen_p10) { name = "p10"; phys_map = &phys_map_p10; + } else if (proc_gen == proc_gen_p11) { + name = "p11"; + phys_map = &phys_map_p10; } prlog(PR_DEBUG, "Assigning physical memory map table for %s\n", name); diff --git a/hw/prd.c b/hw/prd.c index 45d765457f..51bf836906 100644 --- a/hw/prd.c +++ b/hw/prd.c @@ -741,6 +741,7 @@ void prd_init(void) prd_ipoll_mask = PRD_P9_IPOLL_MASK; break; case proc_gen_p10: /* IPOLL regs are the same for p9 and p10 */ + case proc_gen_p11: /* IPOLL regs are the same for p9 and p10/11 */ prd_ipoll_mask_reg = PRD_P9_IPOLL_REG_MASK; prd_ipoll_status_reg = PRD_P9_IPOLL_REG_STATUS; prd_ipoll_mask = PRD_P9_IPOLL_MASK; diff --git a/hw/psi.c b/hw/psi.c index aa7e020c71..75a123948d 100644 --- a/hw/psi.c +++ b/hw/psi.c @@ -266,7 +266,10 @@ static void psi_spurious_fsp_irq(struct psi *psi) prlog(PR_NOTICE, "PSI: Spurious interrupt, attempting clear\n"); - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p11) { + reg = PSIHB_XSCOM_P10_HBCSR_CLR; + bit = PSIHB_XSCOM_P10_HBSCR_FSP_IRQ; + } else if (proc_gen == proc_gen_p10) { reg = PSIHB_XSCOM_P10_HBCSR_CLR; bit = PSIHB_XSCOM_P10_HBSCR_FSP_IRQ; } else if (proc_gen == proc_gen_p9) { @@ -569,6 +572,7 @@ static void psi_p9_mask_unhandled_irq(struct irq_source *is, uint32_t isn) xive_source_mask(is, isn); break; case proc_gen_p10: + case proc_gen_p11: xive2_source_mask(is, isn); return; default: @@ -836,6 +840,7 @@ static void psi_init_interrupts(struct psi *psi) psi_init_p9_interrupts(psi); break; case proc_gen_p10: + case proc_gen_p11: psi_init_p10_interrupts(psi); break; default: @@ -916,6 +921,7 @@ static void psi_create_mm_dtnode(struct psi *psi) break; case proc_gen_p9: case proc_gen_p10: + case proc_gen_p11: dt_add_property_strings(np, "compatible", "ibm,psi", "ibm,power9-psi"); psi_create_p9_int_map(psi, np); diff --git a/hw/sbe.c b/hw/sbe.c index 8595816626..89baaeaa5c 100644 --- a/hw/sbe.c +++ b/hw/sbe.c @@ -18,7 +18,7 @@ void sbe_update_timer_expiry(uint64_t target) { assert(sbe_timer_ok); - if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) p9_sbe_update_timer_expiry(target); #ifdef CONFIG_P8 diff --git a/hw/slw.c b/hw/slw.c index 67b9422efb..feb98dd860 100644 --- a/hw/slw.c +++ b/hw/slw.c @@ -621,7 +621,7 @@ void add_cpu_idle_state_properties(void) states = power9_cpu_idle_states; nr_states = ARRAY_SIZE(power9_cpu_idle_states); } - } else if (chip->type == PROC_CHIP_P10) { + } else if (chip->type == PROC_CHIP_P10 || chip->type == PROC_CHIP_P11) { states = power10_cpu_idle_states; nr_states = ARRAY_SIZE(power10_cpu_idle_states); } else { @@ -652,7 +652,8 @@ void add_cpu_idle_state_properties(void) slw_late_init_p9(chip); xive_late_init(); nx_p9_rng_late_init(); - } else if (chip->type == PROC_CHIP_P10) { + } else if (chip->type == PROC_CHIP_P10 || + chip->type == PROC_CHIP_P11) { slw_late_init_p10(chip); xive2_late_init(); } @@ -935,7 +936,7 @@ void slw_init(void) if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) slw_late_init_p9(chip); } - } else if (proc_gen == proc_gen_p10) { + } else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { for_each_chip(chip) { slw_init_chip_p10(chip); if(slw_image_check_p9(chip)) diff --git a/hw/vas.c b/hw/vas.c index aa3ae3348b..592f7b1cb7 100644 --- a/hw/vas.c +++ b/hw/vas.c @@ -615,7 +615,7 @@ void vas_init(void) if (proc_gen == proc_gen_p9) compat = "ibm,power9-vas-x"; - else if (proc_gen == proc_gen_p10) + else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) compat = "ibm,power10-vas-x"; else return; diff --git a/hw/xive2.c b/hw/xive2.c index d20e3c5ea4..45115666fa 100644 --- a/hw/xive2.c +++ b/hw/xive2.c @@ -2760,11 +2760,11 @@ static void xive_set_quirks(struct xive *x, struct proc_chip *chip __unused) uint64_t quirks = 0; /* This extension is dropped for P10 */ - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) quirks |= XIVE_QUIRK_THREADID_7BITS; /* Broken check on invalid priority when reduced priorities is in use */ - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) quirks |= XIVE_QUIRK_BROKEN_PRIO_CHECK; xive_dbg(x, "setting XIVE quirks to %016llx\n", quirks); diff --git a/hw/xscom.c b/hw/xscom.c index 285f7df129..ca8ebe557e 100644 --- a/hw/xscom.c +++ b/hw/xscom.c @@ -94,7 +94,7 @@ static void xscom_reset(uint32_t gcid, bool need_delay) mtspr(SPR_HMER, HMER_CLR_MASK); /* Setup local and target scom addresses */ - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { recv_status_reg = 0x00090018; log_reg = 0x0090012; err_reg = 0x0090013; @@ -825,7 +825,7 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id) * something up */ if (chip_quirk(QUIRK_NO_F000F)) { - if (proc_gen == proc_gen_p10) + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) val = 0x220DA04980000000UL; /* P10 DD2.0 */ else if (proc_gen == proc_gen_p9) val = 0x203D104980000000UL; /* P9 Nimbus DD2.3 */ @@ -860,6 +860,7 @@ static uint8_t xscom_get_ec_rev(struct proc_chip *chip) table = p9table; break; case proc_gen_p10: + case proc_gen_p11: if (chip->ec_level < 0x20) table = p10dd1table; else @@ -923,8 +924,12 @@ static void xscom_init_chip_info(struct proc_chip *chip) assert(proc_gen == proc_gen_p9); break; case 0xda: - chip->type = PROC_CHIP_P10; - assert(proc_gen == proc_gen_p10); + /* CFAM chip id for p10 and p11 is same. */ + assert(proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11); + if (proc_gen == proc_gen_p10) + chip->type = PROC_CHIP_P10; + else + chip->type = PROC_CHIP_P11; break; default: printf("CHIP: Unknown chip type 0x%02x !!!\n", diff --git a/include/chip.h b/include/chip.h index c90b8a7fe1..fbe7f99fea 100644 --- a/include/chip.h +++ b/include/chip.h @@ -172,6 +172,7 @@ enum proc_chip_type { PROC_CHIP_P9_CUMULUS, PROC_CHIP_P9P, PROC_CHIP_P10, + PROC_CHIP_P11, }; /* Simulator quirks */ diff --git a/include/phb4.h b/include/phb4.h index 29864d28e7..b3eb042f05 100644 --- a/include/phb4.h +++ b/include/phb4.h @@ -252,7 +252,7 @@ static inline void phb4_set_err_pending(struct phb4 *p, bool pending) static inline int phb4_get_opal_id(unsigned int chip_id, unsigned int index) { - if (proc_gen == proc_gen_p10) { + if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) { return chip_id * MAX_PHBS_PER_CHIP_P10 + index; } else { if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P9) diff --git a/include/processor.h b/include/processor.h index 5e5bd9a531..1c913fe7d4 100644 --- a/include/processor.h +++ b/include/processor.h @@ -211,6 +211,7 @@ #define PVR_TYPE_P9 0x004e #define PVR_TYPE_P9P 0x004f /* Axone */ #define PVR_TYPE_P10 0x0080 +#define PVR_TYPE_P11 0x0082 #ifdef __ASSEMBLY__ @@ -269,6 +270,11 @@ static inline bool is_fused_core(uint32_t version) return false; else return true; + } else if (PVR_TYPE(version) == PVR_TYPE_P11) { + if (PVR_CHIP_TYPE(version) & 0x01) + return false; + else + return true; } else return false; } diff --git a/include/skiboot.h b/include/skiboot.h index 88857f8f92..3c6d37d6de 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -101,6 +101,7 @@ enum proc_gen { proc_gen_p8, proc_gen_p9, proc_gen_p10, + proc_gen_p11, }; extern enum proc_gen proc_gen; diff --git a/platforms/ibm-fsp/hostservices.c b/platforms/ibm-fsp/hostservices.c index 1aab668d04..c552a2608e 100644 --- a/platforms/ibm-fsp/hostservices.c +++ b/platforms/ibm-fsp/hostservices.c @@ -639,6 +639,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode) i_core <<= 2; break; case proc_gen_p10: + case proc_gen_p11: i_core &= SPR_PIR_P10_MASK; i_core <<= 2; break; -- 2.44.0 From mahesh at linux.ibm.com Thu Apr 4 16:56:16 2024 From: mahesh at linux.ibm.com (Mahesh Salgaonkar) Date: Thu, 4 Apr 2024 11:26:16 +0530 Subject: [Skiboot] [PATCH 2/4] cpufeatures: Add Power11 support In-Reply-To: <20240404055618.1439108-1-mahesh@linux.ibm.com> References: <20240404055618.1439108-1-mahesh@linux.ibm.com> Message-ID: <20240404055618.1439108-2-mahesh@linux.ibm.com> Update the cpu_feature structure to support Power11. Signed-off-by: Mahesh Salgaonkar --- core/cpufeatures.c | 62 ++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/core/cpufeatures.c b/core/cpufeatures.c index 5620b741dc..5465380a07 100644 --- a/core/cpufeatures.c +++ b/core/cpufeatures.c @@ -49,12 +49,13 @@ #define CPU_P9_DD2_2 (1U << 5) #define CPU_P9_DD2_3 (1U << 6) #define CPU_P10 (1U << 7) +#define CPU_P11 (1U << 8) #define CPU_P9_DD2 (CPU_P9_DD2_0_1|CPU_P9_DD2_2|CPU_P9_DD2_3|CPU_P9P) #define CPU_P8 (CPU_P8_DD1|CPU_P8_DD2) #define CPU_P9 (CPU_P9_DD1|CPU_P9_DD2|CPU_P9P) -#define CPU_ALL (CPU_P8|CPU_P9|CPU_P10) +#define CPU_ALL (CPU_P8|CPU_P9|CPU_P10|CPU_P11) struct cpu_feature { const char *name; @@ -208,7 +209,7 @@ static const struct cpu_feature cpu_features_table[] = { * DAWR1, DAWRX1 etc. */ { "debug-facilities-v31", - CPU_P10, + CPU_P10 | CPU_P11, ISA_V3_1, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -485,7 +486,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B radix based MMU */ { "mmu-radix", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -495,7 +496,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B hash based MMU, new hash pte format, PCTR, etc */ { "mmu-hash-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -505,7 +506,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B wait instruction */ { "wait-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -516,7 +517,7 @@ static const struct cpu_feature cpu_features_table[] = { * XXX: Same question as for idle-nap */ { "idle-stop", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -528,7 +529,7 @@ static const struct cpu_feature cpu_features_table[] = { * system reset SRR1 reason, etc. */ { "hypervisor-virtualization-interrupt", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV, HV_CUSTOM, OS_NONE, -1, -1, -1, @@ -548,7 +549,7 @@ static const struct cpu_feature cpu_features_table[] = { * POWER10 MCE / machine check exception. */ { "machine-check-power10", - CPU_P10, + CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -568,7 +569,7 @@ static const struct cpu_feature cpu_features_table[] = { * POWER10 PMU / performance monitor unit. */ { "performance-monitor-power10", - CPU_P10, + CPU_P10|CPU_P11, ISA_V3_1, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_CUSTOM, -1, -1, -1, @@ -579,7 +580,7 @@ static const struct cpu_feature cpu_features_table[] = { * etc. */ { "system-call-vectored", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_OS|USABLE_PR, HV_NONE, OS_CUSTOM, -1, PPC_BITLSHIFT(51), 52, @@ -590,7 +591,7 @@ static const struct cpu_feature cpu_features_table[] = { * global msgsnd, msgsndp, msgsync, doorbell, etc. */ { "processor-control-facility-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_CUSTOM, OS_NONE, PPC_BITLSHIFT(53), -1, -1, @@ -600,7 +601,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B addpcis instruction */ { "pc-relative-addressing", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -623,7 +624,7 @@ static const struct cpu_feature cpu_features_table[] = { * Large decrementer and hypervisor decrementer */ { "timer-facilities-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS, HV_NONE, OS_NONE, -1, -1, -1, @@ -633,7 +634,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B deliver a random number instruction (darn) */ { "random-number-generator", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, 53, @@ -646,14 +647,14 @@ static const struct cpu_feature cpu_features_table[] = { * mcrxrx, setb */ { "fixed-point-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, NULL, }, { "decimal-integer-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -663,42 +664,42 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B lightweight mffs */ { "floating-point-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, "floating-point", }, { "decimal-floating-point-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, "floating-point-v3 decimal-floating-point", }, { "vector-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, "vector", }, { "vector-scalar-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, "vector-v3 vector-scalar" }, { "vector-binary128", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, 54, "vector-scalar-v3", }, { "vector-binary16", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -708,7 +709,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B external exception for EBB */ { "event-based-branch-v3", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -718,7 +719,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B Atomic Memory Operations (AMO) */ { "atomic-memory-operations", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -728,7 +729,7 @@ static const struct cpu_feature cpu_features_table[] = { * ISAv3.0B Copy-Paste Facility */ { "copy-paste", - CPU_P9|CPU_P10, + CPU_P9|CPU_P10|CPU_P11, ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR, HV_NONE, OS_NONE, -1, -1, -1, @@ -749,7 +750,7 @@ static const struct cpu_feature cpu_features_table[] = { * Enable matrix multiply accumulate. */ { "matrix-multiply-accumulate", - CPU_P10, + CPU_P10|CPU_P11, ISA_V3_1, USABLE_PR, HV_CUSTOM, OS_CUSTOM, -1, -1, 49, @@ -760,7 +761,7 @@ static const struct cpu_feature cpu_features_table[] = { * enabled for when compiling for ISA 3.1. */ { "prefix-instructions", - CPU_P10, + CPU_P10|CPU_P11, ISA_V3_1, USABLE_HV|USABLE_OS|USABLE_PR, HV_HFSCR, OS_FSCR, 13, 13, -1, @@ -1033,6 +1034,13 @@ void dt_add_cpufeatures(struct dt_node *root) cpu_feature_isa = ISA_V3_1; cpu_feature_cpu = CPU_P10; break; + case PVR_TYPE_P11: + if (!cpu_name) + cpu_name = "Power11"; + + cpu_feature_isa = ISA_V3_1; + cpu_feature_cpu = CPU_P11; + break; default: return; } -- 2.44.0 From mahesh at linux.ibm.com Thu Apr 4 16:56:17 2024 From: mahesh at linux.ibm.com (Mahesh Salgaonkar) Date: Thu, 4 Apr 2024 11:26:17 +0530 Subject: [Skiboot] [PATCH 3/4] plat/qemu: add support for Power11 platform In-Reply-To: <20240404055618.1439108-1-mahesh@linux.ibm.com> References: <20240404055618.1439108-1-mahesh@linux.ibm.com> Message-ID: <20240404055618.1439108-3-mahesh@linux.ibm.com> Add support for QEMU simulator for Power11 when it starts supporting "qemu,powernv11" machines. Signed-off-by: Aditya Gupta Signed-off-by: Mahesh Salgaonkar --- core/chip.c | 1 + hw/psi.c | 2 ++ hw/xscom.c | 16 ++++++++++++++-- platforms/qemu/qemu.c | 23 +++++++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/core/chip.c b/core/chip.c index 2576e27a34..b38bb21d6d 100644 --- a/core/chip.c +++ b/core/chip.c @@ -203,6 +203,7 @@ void init_chips(void) dt_node_is_compatible(dt_root, "qemu,powernv8") || dt_node_is_compatible(dt_root, "qemu,powernv9") || dt_node_is_compatible(dt_root, "qemu,powernv10") || + dt_node_is_compatible(dt_root, "qemu,powernv11") || dt_find_by_path(dt_root, "/qemu")) { proc_chip_quirks |= QUIRK_QEMU | QUIRK_NO_DIRECT_CTL | QUIRK_NO_RNG; prlog(PR_NOTICE, "CHIP: Detected QEMU simulator\n"); diff --git a/hw/psi.c b/hw/psi.c index 75a123948d..dde8e7ef34 100644 --- a/hw/psi.c +++ b/hw/psi.c @@ -1027,6 +1027,8 @@ static bool psi_init_psihb(struct dt_node *psihb) psi = psi_probe_p9(chip, base); else if (dt_node_is_compatible(psihb, "ibm,power10-psihb-x")) psi = psi_probe_p10(chip, base); + else if (dt_node_is_compatible(psihb, "ibm,power11-psihb-x")) + psi = psi_probe_p10(chip, base); else { prerror("PSI: Unknown processor type\n"); return false; diff --git a/hw/xscom.c b/hw/xscom.c index ca8ebe557e..3f9a238be4 100644 --- a/hw/xscom.c +++ b/hw/xscom.c @@ -846,6 +846,7 @@ static uint8_t xscom_get_ec_rev(struct proc_chip *chip) { uint64_t ecid2 = 0; int8_t rev; + int8_t proc_gen_num; const int8_t *table; /* 0 1 2 3 4 5 6 7 */ const int8_t p9table[8] = {0, 1, -1, 2, -1, -1, -1, 3}; @@ -876,8 +877,19 @@ static uint8_t xscom_get_ec_rev(struct proc_chip *chip) if (rev < 0) return 0; + switch (proc_gen) { + case proc_gen_p9: + proc_gen_num = 9; break; + case proc_gen_p10: + proc_gen_num = 10; break; + case proc_gen_p11: + proc_gen_num = 11; break; + default: + proc_gen_num = -1; break; + } + prlog(PR_INFO, "P%d DD%i.%i%d detected\n", - proc_gen == proc_gen_p9 ? 9 : 10, + proc_gen_num, 0xf & (chip->ec_level >> 4), chip->ec_level & 0xf, rev); @@ -980,7 +992,7 @@ void xscom_init(void) const char *chip_name; static const char *chip_names[] = { "UNKNOWN", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P", - "P10", + "P10", "P11", }; chip = get_chip(gcid); diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c index 0f6e089fa7..c6c6a50072 100644 --- a/platforms/qemu/qemu.c +++ b/platforms/qemu/qemu.c @@ -76,6 +76,11 @@ static bool qemu_probe_powernv10(void) return qemu_probe_common("qemu,powernv10"); } +static bool qemu_probe_powernv11(void) +{ + return qemu_probe_common("qemu,powernv11"); +} + static void qemu_init(void) { if (!bt_device_present) { @@ -156,3 +161,21 @@ DECLARE_PLATFORM(qemu_powernv10) = { .exit = astbmc_exit, .terminate = ipmi_terminate, }; + +/* + * For a QEMU PowerNV machine using Power11 CPUs + */ +DECLARE_PLATFORM(qemu_powernv11) = { + .name = "QEMU Power11", + .probe = qemu_probe_powernv11, + .bmc = &bmc_plat_ast2600_openbmc, + .init = qemu_init, + .external_irq = astbmc_ext_irq_serirq_cpld, + .cec_power_down = astbmc_ipmi_power_down, + .cec_reboot = astbmc_ipmi_reboot, + .pci_get_slot_info = slot_table_get_slot_info, + .start_preload_resource = flash_start_preload_resource, + .resource_loaded = flash_resource_loaded, + .exit = astbmc_exit, + .terminate = ipmi_terminate, +}; -- 2.44.0 From mahesh at linux.ibm.com Thu Apr 4 16:56:18 2024 From: mahesh at linux.ibm.com (Mahesh Salgaonkar) Date: Thu, 4 Apr 2024 11:26:18 +0530 Subject: [Skiboot] [PATCH 4/4] external/mambo: skiboot.tcl add Power11 config In-Reply-To: <20240404055618.1439108-1-mahesh@linux.ibm.com> References: <20240404055618.1439108-1-mahesh@linux.ibm.com> Message-ID: <20240404055618.1439108-4-mahesh@linux.ibm.com> Setup skiboot.tcl with Power11 config to be boot on Power11 mambo. Signed-off-by: Mahesh Salgaonkar --- external/mambo/skiboot.tcl | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/external/mambo/skiboot.tcl b/external/mambo/skiboot.tcl index 6c0eb5a0d0..cce84d2058 100644 --- a/external/mambo/skiboot.tcl +++ b/external/mambo/skiboot.tcl @@ -175,6 +175,34 @@ if { $default_config == "P10" } { } } +if { $default_config == "P11" } { + # PVR configured for POWER11 DD2.0, LPAR-per-thread + myconf config processor/initial/SIM_CTRL 0x0c1dd60000000000 + if { $mconf(threads) == 8 } { + # Big-core mode. + myconf config processor/initial/PVR 0x00820200 + myconf config processor/initial/SIM_CTRL1 0xc0400c0400040a40 + puts "Set P11 big-core mode" + } else { + # Small-core mode. + myconf config processor/initial/PVR 0x00821200 + myconf config processor/initial/SIM_CTRL1 0xc0400c0401040a40 + if { $mconf(threads) != 1 && $mconf(threads) != 2 && $mconf(threads) != 4 } { + puts "ERROR: Bad threads configuration" + exit + } + if { $mconf(threads) != 4 && $mconf(cpus) != 1 } { + puts "ERROR: Bad threads, cpus configuration" + exit + } + + puts "Set P11 small-core mode" + } + + if { $mconf(numa) } { + myconf config memory_region_id_shift 44 + } +} if { $mconf(numa) } { myconf config memory_regions $mconf(cpus) -- 2.44.0