diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/include/chip.h | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/include/chip.h')
-rw-r--r-- | roms/skiboot/include/chip.h | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/roms/skiboot/include/chip.h b/roms/skiboot/include/chip.h new file mode 100644 index 000000000..bbfc65e3a --- /dev/null +++ b/roms/skiboot/include/chip.h @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __CHIP_H +#define __CHIP_H + +#include <stdint.h> +#include <lock.h> + +#include <ccan/list/list.h> + +/* + * Note on chip IDs: + * + * We carry a "chip_id" around, in the cpu_thread, but also as + * ibm,chip-id properties. + * + * This ID is the HW fabric ID of a chip based on the XSCOM numbering, + * also known as "GCID" (Global Chip ID). + * + * The format of this number is different between chip generations and care must + * be taken when trying to convert between this chip ID and some other + * representation such as PIR values, interrupt-server numbers etc... : + * + */ + +/* + * P8 GCID + * ------- + * + * Global chip ID is a 6 bit number: + * + * NodeID ChipID + * | | | + * |___|___|___|___|___|___| + * + * The the ChipID is 3 bits long, the GCID is the same as the high bits of PIR + */ +#define P8_PIR2GCID(pir) (((pir) >> 7) & 0x3f) + +#define P8_PIR2COREID(pir) (((pir) >> 3) & 0xf) + +#define P8_PIR2THREADID(pir) ((pir) & 0x7) + +/* + * P9 GCID + * ------- + * + * Global chip ID is a 7 bit number: + * + * NodeID ChipID + * | | | + * |___|___|___|___|___|___|___| + * + * Bit 56 is unused according to the manual by we add it to the coreid here, + * thus we have a 6-bit core number. + * + * Note: XIVE Only supports 4-bit chip numbers ... + * + * Upper PIR Bits + * -------------- + * + * Normal-Core Mode: + * 57:61 CoreID + * 62:63 ThreadID + * + * Fused-Core Mode: + * 57:59 FusedQuadID + * 60 FusedCoreID + * 61:63 FusedThreadID + * + * FusedCoreID 0 contains normal-core chiplet 0 and 1 + * FusedCoreID 1 contains normal-core chiplet 2 and 3 + * + * Fused cores have interleaved threads: + * core chiplet 0/2 = t0, t2, t4, t6 + * core chiplet 1/3 = t1, t3, t5, t7 + * + */ +#define P9_PIR2GCID(pir) (((pir) >> 8) & 0x7f) + +#define P9_PIR2COREID(pir) (((pir) >> 2) & 0x3f) + +#define P9_PIR2THREADID(pir) ((pir) & 0x3) + +#define P9_GCID2NODEID(gcid) (((gcid) >> 3) & 0xf) + +#define P9_GCID2CHIPID(gcid) ((gcid) & 0x7) + +#define P9_PIR2FUSEDQUADID(pir) (((pir) >> 4) & 0x7) + +#define P9_PIR2FUSEDCOREID(pir) (((pir) >> 3) & 0x1) + +#define P9_PIR2FUSEDTHREADID(pir) ((pir) & 0x7) + +#define P9_PIRFUSED2NORMALCOREID(pir) \ + (P9_PIR2FUSEDQUADID(pir) << 2) | \ + (P9_PIR2FUSEDCOREID(pir) << 1) | \ + (P9_PIR2FUSEDTHREADID(pir) & 1) + +#define P9_PIRFUSED2NORMALTHREADID(pir) (((pir) >> 1) & 0x3) + +#define P10_PIR2FUSEDCOREID(pir) P9_PIR2FUSEDCOREID(pir) +#define P10_PIRFUSED2NORMALCOREID(pir) P9_PIRFUSED2NORMALCOREID(pir) +#define P10_PIRFUSED2NORMALTHREADID(pir) P9_PIRFUSED2NORMALTHREADID(pir) + +/* P9 specific ones mostly used by XIVE */ +#define P9_PIR2LOCALCPU(pir) ((pir) & 0xff) +#define P9_PIRFROMLOCALCPU(chip, cpu) (((chip) << 8) | (cpu)) + +/* + * P10 PIR + * ------- + * + * PIR layout: + * + * | 49| 50| 51| 52| 53| 54| 55| 56| 57| 58| 59| 60| 61| 62| 63| + * |Spare ID |Topology ID |Sp. |Quad ID |Core ID |Thread ID| + * + * Bit 56 is a spare quad ID. In big-core mode, thread ID extends to bit 61. + * + * P10 GCID + * -------- + * + * - Global chip ID is also called Topology ID. + * - Node ID is called Group ID (? XXX P10). + * + * Global chip ID is a 4 bit number. + * + * There is a topology mode bit that can be 0 or 1, which changes GCID mapping. + * + * Topology mode 0: + * NodeID ChipID + * | | | + * |____|____|____|____| + * + * Topology mode 1: + * NodeID ChipID + * | | | + * |____|____|____|____| + */ +#define P10_PIR2GCID(pir) (((pir) >> 8) & 0xf) + +#define P10_PIR2COREID(pir) (((pir) >> 2) & 0x3f) + +#define P10_PIR2THREADID(pir) ((pir) & 0x3) + +// XXX P10 These depend on the topology mode, how to get that (system type?) +#define P10_GCID2NODEID(gcid, mode) ((mode) == 0 ? ((gcid) >> 1) & 0x7 : ((gcid) >> 2) & 0x3) +#define P10_GCID2CHIPID(gcid, mode) ((mode) == 0 ? (gcid) & 0x1 : (gcid) & 0x3) + +/* P10 specific ones mostly used by XIVE */ +#define P10_PIR2LOCALCPU(pir) ((pir) & 0xff) +#define P10_PIRFROMLOCALCPU(chip, cpu) (((chip) << 8) | (cpu)) + +struct dt_node; +struct centaur_chip; +struct mfsi; +struct xive; +struct lpcm; +struct vas; +struct p9_sbe; +struct p9_dio; + +/* Chip type */ +enum proc_chip_type { + PROC_CHIP_UNKNOWN, + PROC_CHIP_P8_MURANO, + PROC_CHIP_P8_VENICE, + PROC_CHIP_P8_NAPLES, + PROC_CHIP_P9_NIMBUS, + PROC_CHIP_P9_CUMULUS, + PROC_CHIP_P9P, + PROC_CHIP_P10, +}; + +/* Simulator quirks */ +enum proc_chip_quirks { + QUIRK_NO_CHIPTOD = 0x00000001, + QUIRK_MAMBO_CALLOUTS = 0x00000002, + QUIRK_NO_F000F = 0x00000004, + QUIRK_NO_PBA = 0x00000008, + QUIRK_NO_OCC_IRQ = 0x00000010, + QUIRK_SIMICS = 0x00000020, + QUIRK_SLOW_SIM = 0x00000040, + QUIRK_NO_DIRECT_CTL = 0x00000080, + QUIRK_NO_RNG = 0x00000100, + QUIRK_QEMU = 0x00000200, +}; + +extern enum proc_chip_quirks proc_chip_quirks; + +static inline bool chip_quirk(unsigned int q) +{ + return !!(proc_chip_quirks & q); +} + +#define MAX_CHIPS (1 << 6) /* 6-bit chip ID */ + +/* + * For each chip in the system, we maintain this structure + * + * This contains fields used by different modules including + * modules in hw/ but is handy to keep per-chip data + */ +struct proc_chip { + uint32_t id; /* HW Chip ID (GCID) */ + struct dt_node *devnode; /* "xscom" chip node */ + + /* These are only initialized after xcom_init */ + enum proc_chip_type type; + uint32_t ec_level; /* 0xMm (DD1.0 = 0x10) */ + uint8_t ec_rev; /* sub-revision */ + + /* Those two values are only populated on machines with an FSP + * dbob_id = Drawer/Block/Octant/Blade (DBOBID) + * pcid = HDAT processor_chip_id + */ + uint32_t dbob_id; + uint32_t pcid; + + /* If we expect to have an OCC (i.e. P8) and it is functional, + * set TRUE. If something has told us it is not, set FALSE and + * we can not wait for OCCs to init. This is only going to be + * FALSE in a simulator that doesn't simulate OCCs. */ + bool occ_functional; + + /* Used by hw/xscom.c */ + uint64_t xscom_base; + + /* Used by hw/lpc.c */ + struct lpcm *lpc; + + /* Used by hw/slw.c */ + uint64_t slw_base; + uint64_t slw_bar_size; + uint64_t slw_image_size; + + /* Used by hw/homer.c */ + uint64_t homer_base; + uint64_t homer_size; + uint64_t occ_common_base; + uint64_t occ_common_size; + uint8_t throttle; + + /* Must hold capi_lock to change */ + uint8_t capp_phb3_attached_mask; + uint8_t capp_ucode_loaded; + + /* Used by hw/centaur.c */ + struct centaur_chip *centaurs; + + /* Used by hw/p8-i2c.c */ + struct list_head i2cms; + + /* Used by hw/psi.c */ + struct psi *psi; + + /* Used by hw/fsi-master.c */ + struct mfsi *fsi_masters; + + /* Used by hw/xive.c */ + struct xive *xive; + + struct vas *vas; + + /* Used by hw/nx-compress.c */ + uint64_t nx_base; + /* location code of this chip */ + const uint8_t *loc_code; + + /* Used by hw/sbe-p9.c */ + struct p9_sbe *sbe; + + /* Used by hw/dio-p9.c */ + struct p9_dio *dio; + + /* Used during OCC init */ + bool ex_present; + + /* Used by hw/vas.c on p10 */ + uint32_t primary_topology; +}; + +extern uint32_t pir_to_chip_id(uint32_t pir); + +/* + * Note: In P9 fused-core mode, these will return the "normal" + * core ID and thread ID (ie, thread ID 0..3) + */ +extern uint32_t pir_to_core_id(uint32_t pir); +extern uint32_t pir_to_thread_id(uint32_t pir); + +/* In P9 fused core mode, this is the "fused" core ID, in + * normal core mode or P8, this is the same as pir_to_core_id + */ +extern uint32_t pir_to_fused_core_id(uint32_t pir); + +extern struct proc_chip *next_chip(struct proc_chip *chip); + +#define for_each_chip(__c) for (__c=next_chip(NULL); __c; __c=next_chip(__c)) + +extern struct proc_chip *get_chip(uint32_t chip_id); + +extern void init_chips(void); + +/* helper to get number of chips in the system */ +static inline int nr_chips(void) +{ + struct proc_chip *chip; + int nr_chips = 0; + + for_each_chip(chip) + nr_chips++; + + return nr_chips; +} + +/* helper to get location code of a chip */ +static inline const char *chip_loc_code(uint32_t chip_id) +{ + struct proc_chip *chip; + + chip = get_chip(chip_id); + if (!chip) + return NULL; + + return chip->loc_code; +} + +#endif /* __CHIP_H */ + |