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 | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/include')
111 files changed, 17868 insertions, 0 deletions
diff --git a/roms/skiboot/include/affinity.h b/roms/skiboot/include/affinity.h new file mode 100644 index 000000000..88bd285fc --- /dev/null +++ b/roms/skiboot/include/affinity.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * All functions in charge of generating the associativity/affinity + * properties in the device-tree + * + * Copyright 2013-2014 IBM Corp. + */ + +#ifndef __AFFINITY_H +#define __AFFINITY_H + +struct dt_node; +struct cpu_thread; + +extern void add_associativity_ref_point(void); + +extern void add_chip_dev_associativity(struct dt_node *dev); +extern void add_core_associativity(struct cpu_thread *cpu); + +#endif /* __AFFINITY_H */ diff --git a/roms/skiboot/include/asm-utils.h b/roms/skiboot/include/asm-utils.h new file mode 100644 index 000000000..18325a8b3 --- /dev/null +++ b/roms/skiboot/include/asm-utils.h @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __ASM_UTILS_H +#define __ASM_UTILS_H + +/* + * Do NOT use the immediate load helpers with symbols + * only with constants. Symbols will _not_ be resolved + * by the linker since we are building -pie, and will + * instead generate relocs of a type our little built-in + * relocator can't handle + */ + +/* Load an immediate 64-bit value into a register */ +#define LOAD_IMM64(r, e) \ + lis r,(e)@highest; \ + ori r,r,(e)@higher; \ + rldicr r,r, 32, 31; \ + oris r,r, (e)@h; \ + ori r,r, (e)@l; + +/* Load an immediate 32-bit value into a register */ +#define LOAD_IMM32(r, e) \ + lis r,(e)@h; \ + ori r,r,(e)@l; + +/* Load an address via the TOC */ +#define LOAD_ADDR_FROM_TOC(r, e) ld r,e@got(%r2) + +/* This must preserve LR, may only clobber r11-r12, so can't use Linux kernel's + * FIXUP_ENDIAN */ +#define SWITCH_ENDIAN \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0xa64b7b7d; /* mthsrr1 r11 */ \ + .long 0xa602687d; /* mflr r11 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602887d; /* mflr r12 */ \ + .long 0x14008c39; /* addi r12,r12,20 */ \ + .long 0xa64b9a7d; /* mthsrr0 r12 */ \ + .long 0xa603687d; /* mtlr r11 */ \ + .long 0x2402004c /* hrfid */ + +#define FIXUP_ENDIAN \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b 191f; /* Skip trampoline if endian is good */ \ + SWITCH_ENDIAN; /* Do the switch */ \ +191: + +#if HAVE_BIG_ENDIAN +#define OPAL_ENTRY_TO_SKIBOOT_ENDIAN +#else +#define OPAL_ENTRY_TO_SKIBOOT_ENDIAN SWITCH_ENDIAN +#endif + +#endif /* __ASM_UTILS_H */ diff --git a/roms/skiboot/include/ast.h b/roms/skiboot/include/ast.h new file mode 100644 index 000000000..5e932398a --- /dev/null +++ b/roms/skiboot/include/ast.h @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __AST_H +#define __AST_H + +/* + * AHB bus registers + */ + +/* SPI Flash controller #1 (BMC) */ +#define BMC_SPI_FCTL_BASE 0x1E620000 +#define BMC_SPI_FCTL_CE_CTRL (BMC_SPI_FCTL_BASE + 0x04) +#define BMC_SPI_FCTL_CTRL (BMC_SPI_FCTL_BASE + 0x10) +#define BMC_SPI_FREAD_TIMING (BMC_SPI_FCTL_BASE + 0x94) +#define BMC_FLASH_BASE 0x20000000 + +/* SPI Flash controller #2 (PNOR) */ +#define PNOR_SPI_FCTL_BASE 0x1E630000 +#define PNOR_SPI_FCTL_CONF (PNOR_SPI_FCTL_BASE + 0x00) +#define PNOR_SPI_FCTL_CTRL (PNOR_SPI_FCTL_BASE + 0x04) +#define PNOR_SPI_FREAD_TIMING (PNOR_SPI_FCTL_BASE + 0x14) +#define PNOR_FLASH_BASE 0x30000000 + +/* LPC registers */ +#define LPC_BASE 0x1e789000 +#define LPC_HICR6 (LPC_BASE + 0x80) +#define LPC_HICR7 (LPC_BASE + 0x88) +#define LPC_HICR8 (LPC_BASE + 0x8c) +#define LPC_HICRB (LPC_BASE + 0x100) +#define LPC_HICRB_ILPC_DISABLE (1 << 6) +#define LPC_iBTCR0 (LPC_BASE + 0x140) + +/* VUART1 */ +#define VUART1_BASE 0x1e787000 +#define VUART1_GCTRLA (VUART1_BASE + 0x20) +#define VUART1_GCTRLB (VUART1_BASE + 0x24) +#define VUART1_ADDRL (VUART1_BASE + 0x28) +#define VUART1_ADDRH (VUART1_BASE + 0x2c) + +/* SCU registers */ +#define SCU_BASE 0x1e6e2000 +#define SCU_HW_STRAPPING (SCU_BASE + 0x70) +#define SCU_STRAP_SIO_DECODE_DISABLE (1 << 20) +#define SCU_REVISION_ID (SCU_BASE + 0x7C) +#define SCU_REVISION_SOC_FAMILY(x) (((x) >> 24) & 0xff) +#define SCU_REVISION_SOC_FAMILY_2400 0x02 +#define SCU_REVISION_SOC_FAMILY_2500 0x04 +#define SCU_REVISION_HW_REVISION_ID(x) (((x) >> 16) & 0xff) +#define SCU_REVISION_CHIP_BONDING(x) (((x) >> 8) & 0x3) + +/* MCR registers */ +#define MCR_BASE 0x1e6e0000 +#define MCR_CONFIGURATION (MCR_BASE + 0x04) +#define MCR_SCU_MPLL (MCR_BASE + 0x120) +#define MCR_SCU_STRAP (MCR_BASE + 0x170) + +/* + * AHB Accessors + */ +#ifndef __SKIBOOT__ +#include "io.h" +#else + +/* + * Register accessors, return byteswapped values + * (IE. LE registers) + */ +void ast_ahb_writel(uint32_t val, uint32_t reg); +uint32_t ast_ahb_readl(uint32_t reg); + +bool ast_sio_is_enabled(void); +bool ast_sio_init(void); +bool ast_io_init(void); +bool ast_io_is_rw(void); +bool ast_lpc_fw_maps_flash(void); +bool ast_lpc_fw_ipmi_hiomap(void); +bool ast_lpc_fw_mbox_hiomap(void); +bool ast_scratch_reg_is_mbox(void); + +/* UART configuration */ + +bool ast_is_vuart1_enabled(void); +void ast_setup_vuart1(uint16_t io_base, uint8_t irq); +void ast_setup_sio_uart1(uint16_t io_base, uint8_t irq); +void ast_disable_sio_uart1(void); + +/* BT configuration */ +void ast_setup_ibt(uint16_t io_base, uint8_t irq); + +/* MBOX configuration */ +void ast_setup_sio_mbox(uint16_t io_base, uint8_t irq); + +#endif /* __SKIBOOT__ */ + +/* + * SPI Flash controllers + */ +#define AST_SF_TYPE_PNOR 0 +#define AST_SF_TYPE_BMC 1 +#define AST_SF_TYPE_MEM 2 + +struct spi_flash_ctrl; +int ast_sf_open(uint8_t type, struct spi_flash_ctrl **ctrl); +void ast_sf_close(struct spi_flash_ctrl *ctrl); + + +#endif /* __AST_H */ diff --git a/roms/skiboot/include/bitmap.h b/roms/skiboot/include/bitmap.h new file mode 100644 index 000000000..fa3a57fe3 --- /dev/null +++ b/roms/skiboot/include/bitmap.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2016-2017 IBM Corp. */ + +#ifndef __BITMAP_H +#define __BITMAP_H + +#include <stdint.h> +#include <stdbool.h> + +typedef unsigned long bitmap_elem_t; +typedef bitmap_elem_t bitmap_t[]; + +#define BITMAP_ELSZ (sizeof(bitmap_elem_t) << 3) + +/* Number of elements for _n bits (rounded up) */ +#define BITMAP_ELEMS(_n) (((_n) + (BITMAP_ELSZ - 1)) / BITMAP_ELSZ) +/* Number of bytes for _n bits (rounded up) */ +#define BITMAP_BYTES(_n) (BITMAP_ELEMS(_n) * sizeof(bitmap_elem_t)) +/* Bit number within an elemnt for bit _n */ +#define BITMAP_BIT(_n) ((_n) & (BITMAP_ELSZ - 1)) +/* Corresponding mask */ +#define BITMAP_MASK(_n) (1ul << BITMAP_BIT(_n)) +/* Element number for bit _n */ +#define BITMAP_ELEM(_n) ((_n) / BITMAP_ELSZ) + +static inline void bitmap_set_bit(bitmap_t map, unsigned int bit) +{ + map[BITMAP_ELEM(bit)] |= BITMAP_MASK(bit); +} + +static inline void bitmap_clr_bit(bitmap_t map, unsigned int bit) +{ + map[BITMAP_ELEM(bit)] &= ~BITMAP_MASK(bit); +} + +static inline bool bitmap_tst_bit(bitmap_t map, unsigned int bit) +{ + return map[BITMAP_ELEM(bit)] & BITMAP_MASK(bit); +} + +extern int bitmap_find_zero_bit(bitmap_t map, unsigned int start, + unsigned int count); +extern int bitmap_find_one_bit(bitmap_t map, unsigned int start, + unsigned int count); + +#define bitmap_for_each_zero(map, size, bit) \ + for (bit = bitmap_find_zero_bit(map, 0, size); \ + bit >= 0; \ + bit = bitmap_find_zero_bit(map, (bit) + 1, (size) - (bit) - 1)) + +#define bitmap_for_each_one(map, size, bit) \ + for (bit = bitmap_find_one_bit(map, 0, size); \ + bit >= 0; \ + bit = bitmap_find_one_bit(map, (bit) + 1, (size) - (bit) - 1)) + +#endif /* __BITMAP_H */ diff --git a/roms/skiboot/include/bitutils.h b/roms/skiboot/include/bitutils.h new file mode 100644 index 000000000..ac3af4d1c --- /dev/null +++ b/roms/skiboot/include/bitutils.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#ifndef __BITUTILS_H +#define __BITUTILS_H + +/* PPC bit number conversion */ +#ifdef __ASSEMBLY__ +#define PPC_BIT(bit) (0x8000000000000000 >> (bit)) +#define PPC_BIT32(bit) (0x80000000 >> (bit)) +#define PPC_BIT16(bit) (0x8000 >> (bit)) +#define PPC_BIT8(bit) (0x80 >> (bit)) +#else +#define PPC_BIT(bit) (0x8000000000000000UL >> (bit)) +#define PPC_BIT32(bit) (0x80000000UL >> (bit)) +#define PPC_BIT16(bit) (0x8000UL >> (bit)) +#define PPC_BIT8(bit) (0x80UL >> (bit)) +#endif +#define PPC_BITMASK(bs,be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) +#define PPC_BITMASK32(bs,be) ((PPC_BIT32(bs) - PPC_BIT32(be))|PPC_BIT32(bs)) +#define PPC_BITMASK16(bs,be) ((PPC_BIT16(bs) - PPC_BIT16(be))|PPC_BIT16(bs)) +#define PPC_BITMASK8(bs,be) ((PPC_BIT8(bs) - PPC_BIT8(be))|PPC_BIT8(bs)) +#define PPC_BITLSHIFT(be) (63 - (be)) +#define PPC_BITLSHIFT32(be) (31 - (be)) + +/* + * PPC bitmask field manipulation + */ + +/* Find left shift from first set bit in mask */ +#define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1) + +/* Extract field from 'v' according to mask 'm' */ +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) + +/* Set field specified by mask 'm' of 'v' to value 'val' + * NOTE: 'v' isn't modified, the combined result is returned + */ +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) + +#endif /* __BITUTILS_H */ diff --git a/roms/skiboot/include/bt.h b/roms/skiboot/include/bt.h new file mode 100644 index 000000000..dd2e7b65a --- /dev/null +++ b/roms/skiboot/include/bt.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __BT_H +#define __BT_H + +/* Initialise the BT interface */ +void bt_init(void); + +#endif diff --git a/roms/skiboot/include/buddy.h b/roms/skiboot/include/buddy.h new file mode 100644 index 000000000..5eaf18d64 --- /dev/null +++ b/roms/skiboot/include/buddy.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Simple power-of-two buddy allocation mechanism. + * + * Copyright 2016 IBM Corp. + */ + +#ifndef __BUDDY_H +#define __BUDDY_H + +#include "bitmap.h" + +#define BUDDY_MAX_ORDER 30 + +struct buddy { + /* max_order is both the height of the tree - 1 and the ^2 of the + * size of the lowest level. + * + * So if we have 512k elements, max_order is 19, which gives us + * a 20 levels tree. + * + * The max supported order is 30 for now. We can increase that + * later if really needed but the performance is going to be + * already pretty bad if we go near that limit. + */ + unsigned int max_order; + + /* For each order, we keep track of how many free modes we + * have there to speed up searches. + */ + unsigned int freecounts[BUDDY_MAX_ORDER + 1]; + bitmap_elem_t map[]; +}; + +extern struct buddy *buddy_create(unsigned int max_order); +extern void buddy_destroy(struct buddy *b); + +extern int buddy_alloc(struct buddy *b, unsigned int order); +extern bool buddy_reserve(struct buddy *b, unsigned int index, unsigned int order); +extern void buddy_free(struct buddy *b, unsigned int index, unsigned int order); +extern void buddy_reset(struct buddy *b); + +#endif /* __BUDDY_H */ diff --git a/roms/skiboot/include/cache-p9.h b/roms/skiboot/include/cache-p9.h new file mode 100644 index 000000000..e763433b6 --- /dev/null +++ b/roms/skiboot/include/cache-p9.h @@ -0,0 +1,22 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CACHE_P9_H +#define __CACHE_P9_H + +int64_t purge_l2_l3_caches(void); + +#endif diff --git a/roms/skiboot/include/capp.h b/roms/skiboot/include/capp.h new file mode 100644 index 000000000..28c12bdae --- /dev/null +++ b/roms/skiboot/include/capp.h @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __CAPP_H +#define __CAPP_H + +/* + * eyecatcher PHB3: 'CAPPLIDH' in ASCII + * eyecatcher PHB4: 'CAPPLIDH' in ASCII + */ +struct capp_lid_hdr { + be64 eyecatcher; + be64 version; + be64 lid_no; + be64 pad; + be64 ucode_offset; + be64 total_size; +}; + +struct capp_ucode_data_hdr { + be64 eyecatcher; /* 'CAPPUCOD' in ASCII */ + u8 version; + u8 reg; + u8 reserved[2]; + be32 chunk_count; /* Num of 8-byte chunks that follow */ +}; + +struct capp_ucode_data { + struct capp_ucode_data_hdr hdr; + be64 data[]; +}; + +struct capp_ucode_lid { + be64 eyecatcher; /* 'CAPPULID' in ASCII */ + be64 version; + be64 data_size; /* Total size of all capp microcode data */ + u8 reserved[40]; + struct capp_ucode_data data; /* This repeats */ +}; + +enum capp_reg { + apc_master_cresp = 0x1, + apc_master_uop_table = 0x2, + snp_ttype = 0x3, + snp_uop_table = 0x4, + apt_master_capi_ctrl = 0x5, + snoop_capi_cnfg = 0x6, + canned_presp_map0 = 0x7, + canned_presp_map1 = 0x8, + canned_presp_map2 = 0x9, + flush_sue_state_map = 0xA, + apc_master_powerbus_ctrl = 0xB +}; + +struct capp_info { + unsigned int capp_index; + unsigned int phb_index; + uint64_t capp_fir_reg; + uint64_t capp_fir_mask_reg; + uint64_t capp_fir_action0_reg; + uint64_t capp_fir_action1_reg; + uint64_t capp_err_status_ctrl_reg; +}; + +struct capp_ops { + int64_t (*get_capp_info)(int, struct phb *, struct capp_info *); +}; + +struct capp { + struct phb *phb; + unsigned int capp_index; + uint64_t capp_xscom_offset; + uint64_t attached_pe; + uint64_t chip_id; +}; + +struct proc_chip; +extern struct lock capi_lock; +extern struct capp_ops capi_ops; + +extern bool capp_ucode_loaded(struct proc_chip *chip, unsigned int index); + +extern int64_t capp_load_ucode(unsigned int chip_id, uint32_t opal_id, + unsigned int index, u64 lid_eyecatcher, + uint32_t reg_offset, + uint64_t apc_master_addr, + uint64_t apc_master_write, + uint64_t snp_array_addr, + uint64_t snp_array_write); + +extern int64_t capp_get_info(int chip_id, struct phb *phb, + struct capp_info *info); + + +/* Helpers to read/write capp registers */ +extern int64_t capp_xscom_read(struct capp *capp, int64_t off, uint64_t *val); +extern int64_t capp_xscom_write(struct capp *capp, int64_t off, uint64_t val); +#endif /* __CAPP_H */ diff --git a/roms/skiboot/include/cec.h b/roms/skiboot/include/cec.h new file mode 100644 index 000000000..d51238f2c --- /dev/null +++ b/roms/skiboot/include/cec.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __CEC_H +#define __CEC_H + +#include <stdint.h> + +/* This represent an IO Hub and contains the function pointers + * for the IO Hub related OPAL ops and other internal functions + */ + +struct io_hub; + +struct io_hub_ops { + /* OPAL_PCI_GET_HUB_DIAG_DATA */ + int64_t (*get_diag_data)(struct io_hub *hub, void *diag_buffer, + uint64_t diag_buffer_len); + + /* Called on fast reset */ + void (*reset)(struct io_hub *hub); +}; + +struct io_hub { + uint32_t hub_id; + const struct io_hub_ops *ops; +}; + +extern struct io_hub *cec_get_hub_by_id(uint32_t hub_id); + +extern void cec_reset(void); +extern void cec_register(struct io_hub *hub); + +#endif /* __CEC_H */ diff --git a/roms/skiboot/include/centaur.h b/roms/skiboot/include/centaur.h new file mode 100644 index 000000000..9845946bb --- /dev/null +++ b/roms/skiboot/include/centaur.h @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#ifndef __CENTAUR_H +#define __CENTAUR_H + +#include <stdint.h> +#include <lock.h> + +#include <ccan/list/list.h> + +struct centaur_chip { + bool valid; + bool online; + uint8_t ec_level; + uint32_t part_id; + uint32_t fsi_master_chip_id; + uint32_t fsi_master_port; + uint32_t fsi_master_engine; + uint32_t scache_disable_count; + bool scache_was_enabled; + uint32_t error_count; + struct lock lock; + + struct scom_controller scom; + + /* Used by hw/p8-i2c.c */ + struct list_head i2cms; +}; + +extern int64_t centaur_disable_sensor_cache(uint32_t part_id); +extern int64_t centaur_enable_sensor_cache(uint32_t part_id); + +extern void centaur_init(void); + +extern struct centaur_chip *get_centaur(uint32_t part_id); + +#endif /* __CENTAUR_H */ 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 */ + diff --git a/roms/skiboot/include/chiptod.h b/roms/skiboot/include/chiptod.h new file mode 100644 index 000000000..50b6ab9b8 --- /dev/null +++ b/roms/skiboot/include/chiptod.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * The ChipTOD is the HW facility that maintains a synchronized + * time base across the fabric. + * + * Copyright 2013-2019 IBM Corp. + */ + +#ifndef __CHIPTOD_H +#define __CHIPTOD_H + +enum chiptod_topology { + chiptod_topo_unknown = -1, + chiptod_topo_primary = 0, + chiptod_topo_secondary = 1, +}; + +extern void chiptod_init(void); +extern bool chiptod_wakeup_resync(void); +extern int chiptod_recover_tb_errors(bool *out_resynced); +extern bool tfmr_recover_local_errors(uint64_t tfmr); +extern bool recover_corrupt_tfmr(void); +extern void tfmr_cleanup_core_errors(uint64_t tfmr); +extern int tfmr_clear_core_errors(uint64_t tfmr); +extern bool chiptod_adjust_topology(enum chiptod_topology topo, bool enable); +extern bool chiptod_capp_timebase_sync(unsigned int chip_id, uint32_t tfmr_addr, + uint32_t tb_addr, uint32_t offset); +extern int chiptod_recover_tod_errors(void); + +#endif /* __CHIPTOD_H */ diff --git a/roms/skiboot/include/cmpxchg.h b/roms/skiboot/include/cmpxchg.h new file mode 100644 index 000000000..0304e9134 --- /dev/null +++ b/roms/skiboot/include/cmpxchg.h @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __CMPXCHG_H +#define __CMPXCHG_H + +#ifndef __TEST__ +/* + * Bare cmpxchg, no barriers. + */ +static inline uint32_t __cmpxchg32(uint32_t *mem, uint32_t old, uint32_t new) +{ + uint32_t prev; + + asm volatile( + "# __cmpxchg32 \n" + "1: lwarx %0,0,%2 \n" + " cmpw %0,%3 \n" + " bne- 2f \n" + " stwcx. %4,0,%2 \n" + " bne- 1b \n" + "2: \n" + + : "=&r"(prev), "+m"(*mem) + : "r"(mem), "r"(old), "r"(new) + : "cr0"); + + return prev; +} + +static inline uint64_t __cmpxchg64(uint64_t *mem, uint64_t old, uint64_t new) +{ + uint64_t prev; + + asm volatile( + "# __cmpxchg64 \n" + "1: ldarx %0,0,%2 \n" + " cmpd %0,%3 \n" + " bne- 2f \n" + " stdcx. %4,0,%2 \n" + " bne- 1b \n" + "2: \n" + + : "=&r"(prev), "+m"(*mem) + : "r"(mem), "r"(old), "r"(new) + : "cr0"); + + return prev; +} + +static inline uint32_t cmpxchg32(uint32_t *mem, uint32_t old, uint32_t new) +{ + uint32_t prev; + + sync(); + prev = __cmpxchg32(mem, old,new); + sync(); + + return prev; +} +#endif /* __TEST_ */ + +#endif /* __CMPXCHG_H */ + + diff --git a/roms/skiboot/include/compiler.h b/roms/skiboot/include/compiler.h new file mode 100644 index 000000000..a9ccfae1c --- /dev/null +++ b/roms/skiboot/include/compiler.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __COMPILER_H +#define __COMPILER_H + +#ifndef __ASSEMBLY__ + +#include <stddef.h> + +/* Macros for various compiler bits and pieces */ +#define __packed __attribute__((packed)) +#define __align(x) __attribute__((__aligned__(x))) +#define __unused __attribute__((unused)) +#define __used __attribute__((used)) +#define __section(x) __attribute__((__section__(x))) +#define __noreturn __attribute__((noreturn)) +/* not __const as this has a different meaning (const) */ +#define __attrconst __attribute__((const)) +#define __warn_unused_result __attribute__((warn_unused_result)) +#define __noinline __attribute__((noinline)) + +#if 0 /* Provided by gcc stddef.h */ +#define offsetof(type,m) __builtin_offsetof(type,m) +#endif + +#define __nomcount __attribute__((no_instrument_function)) + +/* Compiler barrier */ +static inline void barrier(void) +{ + asm volatile("" : : : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/* Stringification macro */ +#define __tostr(x) #x +#define tostr(x) __tostr(x) + +#endif /* __COMPILER_H */ diff --git a/roms/skiboot/include/config.h b/roms/skiboot/include/config.h new file mode 100644 index 000000000..fd9521fa2 --- /dev/null +++ b/roms/skiboot/include/config.h @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* Alignment to which skiboot lays out memory. */ +#define PAGE_SIZE 0x10000 + +#define HAVE_TYPEOF 1 +#define HAVE_BUILTIN_TYPES_COMPATIBLE_P 1 + +/* Keep -Wundef happy by defining whatever isn't on commandline to 0 */ +#if defined(HAVE_LITTLE_ENDIAN) && HAVE_LITTLE_ENDIAN +#define HAVE_BIG_ENDIAN 0 +#endif +#if defined(HAVE_BIG_ENDIAN) && HAVE_BIG_ENDIAN +#define HAVE_LITTLE_ENDIAN 0 +#endif + +/* We don't have a byteswap.h, and thus no bswap_64 */ +#define HAVE_BYTESWAP_H 0 +#define HAVE_BSWAP_64 0 + +/* + * Build options. + */ + +/* Enable lock debugging */ +#define DEBUG_LOCKS 1 + +/* Enable printing of backtraces when locks not released */ +#ifdef DEBUG +#define DEBUG_LOCKS_BACKTRACE 1 +#else +//#define DEBUG_LOCKS_BACKTRACE 1 +#endif + +/* Enable lock dependency checker */ +#define DEADLOCK_CHECKER 1 + +/* Enable OPAL entry point tracing */ +//#define OPAL_TRACE_ENTRY 1 + +/* Enable tracing of event state change */ +//#define OPAL_TRACE_EVT_CHG 1 + +/* Enable various levels of OPAL_console debug */ +//#define OPAL_DEBUG_CONSOLE_IO 1 +//#define OPAL_DEBUG_CONSOLE_POLL 1 + +/* Enable this to force all writes to the in-memory console to + * be mirrored on the mambo console + */ +//#define MAMBO_DEBUG_CONSOLE 1 + +/* Enable this to hookup SkiBoot log to the DVS console */ +#define DVS_CONSOLE 1 + +/* Enable this to force the dummy console to the kernel. + * (ie, an OPAL console that injects into skiboot own console) + * Where possible, leave this undefined and enable it dynamically using + * the chosen->sapphire,enable-dummy-console in the device tree. + * + * Note: This only gets enabled if there is no FSP console. If there + * is one it always takes over for now. This also cause the LPC UART + * node to be marked "reserved" so Linux doesn't instanciate a 8250 + * driver for it. + */ +//#define FORCE_DUMMY_CONSOLE 1 + +/* Enable this to disable setting of the output pending event when + * sending things on the console. The FSP is very slow to consume + * and older kernels wait after each character during early boot so + * things get very slow. Eventually, we may want to create an OPAL + * API for the kernel to activate or deactivate that functionality + */ +#define DISABLE_CON_PENDING_EVT 1 + +#endif /* __CONFIG_H */ + diff --git a/roms/skiboot/include/console.h b/roms/skiboot/include/console.h new file mode 100644 index 000000000..02fc7a4b6 --- /dev/null +++ b/roms/skiboot/include/console.h @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __CONSOLE_H +#define __CONSOLE_H + +#include "unistd.h" + +/* + * Our internal console uses the format of BML new-style in-memory + * console and supports input for setups without a physical console + * facility or FSP. + * + * (This is v3 of the format, the previous one sucked) + */ +struct memcons { + __be64 magic; +#define MEMCONS_MAGIC 0x6630696567726173LL + __be64 obuf_phys; + __be64 ibuf_phys; + __be32 obuf_size; + __be32 ibuf_size; + __be32 out_pos; +#define MEMCONS_OUT_POS_WRAP 0x80000000u +#define MEMCONS_OUT_POS_MASK 0x00ffffffu + __be32 in_prod; + __be32 in_cons; +}; + +extern struct memcons memcons; + +#define INMEM_CON_IN_LEN 16 +#define INMEM_CON_OUT_LEN (INMEM_CON_LEN - INMEM_CON_IN_LEN) + +/* Console driver */ +struct con_ops { + size_t (*write)(const char *buf, size_t len); + size_t (*read)(char *buf, size_t len); + bool (*poll_read)(void); +}; + +struct opal_con_ops { + const char *name; + + /* + * OPAL console driver specific init function. + */ + void (*init)(void); + + int64_t (*write)(int64_t term, __be64 *__len, const uint8_t *buf); + int64_t (*read)(int64_t term, __be64 *__len, uint8_t *buf); + + /* + * returns the amount of space available in the console write buffer + */ + int64_t (*space)(int64_t term_number, __be64 *__length); + + /* + * Forces the write buffer to be flushed by the driver + */ + int64_t (*flush)(int64_t term_number); +}; + +extern bool flush_console(void); + +extern void set_console(struct con_ops *driver); +extern void set_opal_console(struct opal_con_ops *driver); +extern void init_opal_console(void); + +extern void console_complete_flush(void); + +extern size_t mambo_console_write(const char *buf, size_t count); +extern void enable_mambo_console(void); + +ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count); + +extern void clear_console(void); +extern void memcons_add_properties(void); +extern void dummy_console_add_nodes(void); + +struct dt_node *add_opal_console_node(int index, const char *type, + uint32_t write_buffer_size); + +/* OPAL console drivers */ +extern struct opal_con_ops uart_opal_con; +extern struct opal_con_ops fsp_opal_con; +extern struct opal_con_ops dummy_opal_con; + +void mprintf(const char *fmt, ...); + +#endif /* __CONSOLE_H */ diff --git a/roms/skiboot/include/cpu.h b/roms/skiboot/include/cpu.h new file mode 100644 index 000000000..b0c78ce62 --- /dev/null +++ b/roms/skiboot/include/cpu.h @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __CPU_H +#define __CPU_H + +#include <processor.h> +#include <ccan/list/list.h> +#include <lock.h> +#include <device.h> +#include <opal.h> +#include <stack.h> +#include <timer.h> + +/* + * cpu_thread is our internal structure representing each + * thread in the system + */ + +enum cpu_thread_state { + cpu_state_no_cpu = 0, /* Nothing there */ + cpu_state_unknown, /* In PACA, not called in yet */ + cpu_state_unavailable, /* Not available */ + cpu_state_fast_reboot_entry, /* Called back into OPAL, real mode */ + cpu_state_present, /* Assumed to spin in asm entry */ + cpu_state_active, /* Secondary called in */ + cpu_state_os, /* Under OS control */ + cpu_state_disabled, /* Disabled by us due to error */ + cpu_state_rvwinkle, /* Doing an rvwinkle cycle */ +}; + +struct cpu_job; +struct xive_cpu_state; + +struct cpu_thread { + /* + * "stack_guard" must be at offset 0 to match the + * -mstack-protector-guard-offset=0 statement in the Makefile + */ + uint64_t stack_guard; + uint32_t pir; + uint32_t server_no; + uint32_t chip_id; + bool is_secondary; + bool is_fused_core; + struct cpu_thread *primary; + struct cpu_thread *ec_primary; + enum cpu_thread_state state; + struct dt_node *node; + struct trace_info *trace; + uint64_t save_r1; + void *icp_regs; + uint32_t in_opal_call; + uint32_t quiesce_opal_call; + uint64_t entered_opal_call_at; + uint32_t con_suspend; + struct list_head locks_held; + bool con_need_flush; + bool in_mcount; + bool in_poller; + bool in_reinit; + bool in_fast_sleep; + bool in_sleep; + bool in_idle; + uint32_t hbrt_spec_wakeup; /* primary only */ + uint64_t save_l2_fir_action1; + uint64_t current_token; +#ifdef STACK_CHECK_ENABLED + int64_t stack_bot_mark; + uint64_t stack_bot_pc; + uint64_t stack_bot_tok; +#define CPU_BACKTRACE_SIZE 60 + struct bt_entry stack_bot_bt[CPU_BACKTRACE_SIZE]; + struct bt_metadata stack_bot_bt_metadata; +#endif + struct lock job_lock; + struct list_head job_queue; + uint32_t job_count; + bool job_has_no_return; + /* + * Per-core mask tracking for threads in HMI handler and + * a cleanup done bit. + * [D][TTTTTTTT] + * + * The member 'core_hmi_state' is primary only. + * The 'core_hmi_state_ptr' member from all secondry cpus will point + * to 'core_hmi_state' member in primary cpu. + */ + uint32_t core_hmi_state; /* primary only */ + uint32_t *core_hmi_state_ptr; + bool tb_invalid; + bool tb_resynced; + + /* For use by XICS emulation on XIVE */ + struct xive_cpu_state *xstate; + + /* + * For direct controls scoms, including special wakeup. + */ + struct lock dctl_lock; /* primary only */ + bool dctl_stopped; /* per thread */ + uint32_t special_wakeup_count; /* primary */ + + /* + * For reading DTS sensors async + */ + struct lock dts_lock; + struct timer dts_timer; + __be64 *sensor_data; + u32 sensor_attr; + u32 token; + bool dts_read_in_progress; + +#ifdef DEBUG_LOCKS + /* The lock requested by this cpu, used for deadlock detection */ + struct lock *requested_lock; +#endif +}; + +/* This global is set to 1 to allow secondaries to callin, + * typically set after the primary has allocated the cpu_thread + * array and stacks + */ +extern unsigned long cpu_secondary_start; + +/* Max PIR in the system */ +extern unsigned int cpu_max_pir; + +/* Max # of threads per core */ +extern unsigned int cpu_thread_count; + +/* Boot CPU. */ +extern struct cpu_thread *boot_cpu; + +extern void __nomcount cpu_relax(void); + +/* Initialize CPUs */ +void pre_init_boot_cpu(void); +void init_boot_cpu(void); +void init_cpu_max_pir(void); +void init_all_cpus(void); + +/* This brings up our secondaries */ +extern void cpu_bringup(void); + +/* This is called by secondaries as they call in */ +extern void cpu_callin(struct cpu_thread *cpu); + +/* For cpus which fail to call in. */ +extern void cpu_remove_node(const struct cpu_thread *t); + +/* Find CPUs using different methods */ +extern struct cpu_thread *find_cpu_by_chip_id(u32 chip_id); +extern struct cpu_thread *find_cpu_by_node(struct dt_node *cpu); +extern struct cpu_thread *find_cpu_by_server(u32 server_no); +extern struct cpu_thread *find_cpu_by_pir(u32 pir); + +/* Used for lock internals to avoid re-entrancy */ +extern struct cpu_thread __nomcount *find_cpu_by_pir_nomcount(u32 pir); + +extern struct dt_node *get_cpu_node(u32 pir); + +/* Iterator */ +extern struct cpu_thread *first_cpu(void); +extern struct cpu_thread *next_cpu(struct cpu_thread *cpu); + +/* WARNING: CPUs that have been picked up by the OS are no longer + * appearing as available and can not have jobs scheduled + * on them. Essentially that means that after the OS is + * fully started, all CPUs are seen as unavailable from + * this API standpoint. + */ + +static inline bool cpu_is_present(struct cpu_thread *cpu) +{ + return cpu->state >= cpu_state_present; +} + +static inline bool cpu_is_available(struct cpu_thread *cpu) +{ + return cpu->state == cpu_state_active || + cpu->state == cpu_state_rvwinkle; +} + +extern struct cpu_thread *first_available_cpu(void); +extern struct cpu_thread *next_available_cpu(struct cpu_thread *cpu); +extern struct cpu_thread *first_present_cpu(void); +extern struct cpu_thread *next_present_cpu(struct cpu_thread *cpu); +extern struct cpu_thread *first_ungarded_cpu(void); +extern struct cpu_thread *next_ungarded_cpu(struct cpu_thread *cpu); +extern struct cpu_thread *first_ungarded_primary(void); +extern struct cpu_thread *next_ungarded_primary(struct cpu_thread *cpu); + +#define for_each_cpu(cpu) \ + for (cpu = first_cpu(); cpu; cpu = next_cpu(cpu)) + +#define for_each_available_cpu(cpu) \ + for (cpu = first_available_cpu(); cpu; cpu = next_available_cpu(cpu)) + +#define for_each_present_cpu(cpu) \ + for (cpu = first_present_cpu(); cpu; cpu = next_present_cpu(cpu)) + +#define for_each_ungarded_cpu(cpu) \ + for (cpu = first_ungarded_cpu(); cpu; cpu = next_ungarded_cpu(cpu)) + +#define for_each_ungarded_primary(cpu) \ + for (cpu = first_ungarded_primary(); cpu; cpu = next_ungarded_primary(cpu)) + +extern struct cpu_thread *first_available_core_in_chip(u32 chip_id); +extern struct cpu_thread *next_available_core_in_chip(struct cpu_thread *cpu, u32 chip_id); +extern u8 get_available_nr_cores_in_chip(u32 chip_id); + +#define for_each_available_core_in_chip(core, chip_id) \ + for (core = first_available_core_in_chip(chip_id); core; \ + core = next_available_core_in_chip(core, chip_id)) + +/* Return the caller CPU (only after init_cpu_threads) */ +#ifndef __TEST__ +register struct cpu_thread *__this_cpu asm("r16"); +#else +struct cpu_thread *__this_cpu; +#endif + +static inline __nomcount struct cpu_thread *this_cpu(void) +{ + return __this_cpu; +} + +/* + * Note: On POWER9 fused core, cpu_get_thread_index() and cpu_get_core_index() + * return respectively the thread number within a fused core (0..7) and + * the fused core number. If you want the EC (small core) number, you have + * to use the low level pir_to_core_id() and pir_to_thread_id(). + */ +/* Get the thread # of a cpu within the core */ +static inline uint32_t cpu_get_thread_index(struct cpu_thread *cpu) +{ + return cpu->pir - cpu->primary->pir; +} + +/* Get the core # of a cpu within the core */ +extern uint32_t cpu_get_core_index(struct cpu_thread *cpu); + +/* Get the PIR of thread 0 of the same core */ +static inline uint32_t cpu_get_thread0(struct cpu_thread *cpu) +{ + return cpu->primary->pir; +} + +static inline bool cpu_is_thread0(struct cpu_thread *cpu) +{ + return cpu->primary == cpu; +} + +static inline bool cpu_is_core_chiplet_primary(struct cpu_thread *cpu) +{ + return cpu->is_fused_core & (cpu_get_thread_index(cpu) == 1); +} + +static inline bool cpu_is_sibling(struct cpu_thread *cpu1, + struct cpu_thread *cpu2) +{ + return cpu1->primary == cpu2->primary; +} + +/* Called when some error condition requires disabling a core */ +void cpu_disable_all_threads(struct cpu_thread *cpu); + +/* Allocate & queue a job on target CPU */ +extern struct cpu_job *__cpu_queue_job(struct cpu_thread *cpu, + const char *name, + void (*func)(void *data), void *data, + bool no_return); + +static inline struct cpu_job *cpu_queue_job(struct cpu_thread *cpu, + const char *name, + void (*func)(void *data), + void *data) +{ + return __cpu_queue_job(cpu, name, func, data, false); +} + +extern struct cpu_job *cpu_queue_job_on_node(uint32_t chip_id, + const char *name, + void (*func)(void *data), void *data); + + +/* Poll job status, returns true if completed */ +extern bool cpu_poll_job(struct cpu_job *job); + +/* Synchronously wait for a job to complete, this will + * continue handling the FSP mailbox if called from the + * boot CPU. Set free_it to free it automatically. + */ +extern void cpu_wait_job(struct cpu_job *job, bool free_it); + +/* Called by init to process jobs */ +extern void cpu_process_jobs(void); +/* Fallback to running jobs synchronously for global jobs */ +extern void cpu_process_local_jobs(void); +/* Check if there's any job pending */ +bool cpu_check_jobs(struct cpu_thread *cpu); + +/* Set/clear HILE on all CPUs */ +void cpu_set_hile_mode(bool hile); + +/* OPAL sreset vector in place at 0x100 */ +void cpu_set_sreset_enable(bool sreset_enabled); + +/* IPI for PM modes is enabled */ +void cpu_set_ipi_enable(bool sreset_enabled); + +static inline void cpu_give_self_os(void) +{ + __this_cpu->state = cpu_state_os; +} + +extern unsigned long __attrconst cpu_stack_bottom(unsigned int pir); +extern unsigned long __attrconst cpu_stack_top(unsigned int pir); +extern unsigned long __attrconst cpu_emergency_stack_top(unsigned int pir); + +extern void cpu_idle_job(void); +extern void cpu_idle_delay(unsigned long delay); + +extern void cpu_fast_reboot_complete(void); + +int dctl_set_special_wakeup(struct cpu_thread *t); +int dctl_clear_special_wakeup(struct cpu_thread *t); +int dctl_core_is_gated(struct cpu_thread *t); + +extern void exit_uv_mode(int); +void cpu_disable_pef(void); + +#endif /* __CPU_H */ diff --git a/roms/skiboot/include/debug_descriptor.h b/roms/skiboot/include/debug_descriptor.h new file mode 100644 index 000000000..3ac487b00 --- /dev/null +++ b/roms/skiboot/include/debug_descriptor.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __DEBUG_DESCRIPTOR_H +#define __DEBUG_DESCRIPTOR_H + +#define OPAL_BOOT_COMPLETE 0x1 +/* Debug descriptor. This structure is pointed to by the word at offset + * 0x80 in the sapphire binary + */ +struct debug_descriptor { + u8 eye_catcher[8]; /* "OPALdbug" */ +#define DEBUG_DESC_VERSION 1 + __be32 version; + u8 console_log_levels; /* high 4 bits in memory, + * low 4 bits driver (e.g. uart). */ + u8 state_flags; /* various state flags - OPAL_BOOT_COMPLETE etc */ + __be16 reserved2; + __be32 reserved[2]; + + /* Memory console */ + __be64 memcons_phys; + __be32 memcons_tce; + __be32 memcons_obuf_tce; + __be32 memcons_ibuf_tce; + + /* Traces */ + __be64 trace_mask; + __be32 num_traces; +#define DEBUG_DESC_MAX_TRACES 256 + __be64 trace_phys[DEBUG_DESC_MAX_TRACES]; + __be32 trace_size[DEBUG_DESC_MAX_TRACES]; + __be32 trace_tce[DEBUG_DESC_MAX_TRACES]; + __be16 trace_pir[DEBUG_DESC_MAX_TRACES]; +}; +extern struct debug_descriptor debug_descriptor; + +static inline bool opal_booting(void) +{ + return !(debug_descriptor.state_flags & OPAL_BOOT_COMPLETE); +} + +#endif diff --git a/roms/skiboot/include/device.h b/roms/skiboot/include/device.h new file mode 100644 index 000000000..93fb90ff4 --- /dev/null +++ b/roms/skiboot/include/device.h @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __DEVICE_H +#define __DEVICE_H +#include <ccan/list/list.h> +#include <ccan/short_types/short_types.h> +#include <compiler.h> + +/* Any property or node with this prefix will not be passed to the kernel. */ +#define DT_PRIVATE "skiboot," + +/* + * An in-memory representation of a node in the device tree. + * + * This is trivially flattened into an fdt. + * + * Note that the add_* routines will make a copy of the name if it's not + * a read-only string (ie. usually a string literal). + */ +struct dt_property { + struct list_node list; + const char *name; + size_t len; + char prop[/* len */]; +}; + +struct dt_node { + const char *name; + struct list_node list; + struct list_head properties; + struct list_head children; + struct dt_node *parent; + u32 phandle; +}; + +/* This is shared with device_tree.c .. make it static when + * the latter is gone (hopefully soon) + */ +extern u32 last_phandle; + +extern struct dt_node *dt_root; +extern struct dt_node *dt_chosen; + +/* Create a root node: ie. a parentless one. */ +struct dt_node *dt_new_root(const char *name); + +/* Graft a root node into this tree. */ +bool dt_attach_root(struct dt_node *parent, struct dt_node *root); + +/* Wrappers for last_phandle operations */ +static inline u32 get_last_phandle(void) +{ + return last_phandle; +} + +static inline void set_last_phandle(u32 phandle) +{ + last_phandle = phandle; +} + +static inline u32 new_phandle(void) +{ + return ++last_phandle; +} + +/* Add a child node. */ +struct dt_node *dt_new(struct dt_node *parent, const char *name); +struct dt_node *dt_new_addr(struct dt_node *parent, const char *name, + uint64_t unit_addr); +struct dt_node *dt_new_2addr(struct dt_node *parent, const char *name, + uint64_t unit_addr0, uint64_t unit_addr1); +struct dt_node *dt_new_check(struct dt_node *parent, const char *name); + +/* Copy node to new parent, including properties and subnodes */ +struct dt_node *dt_copy(struct dt_node *node, struct dt_node *parent); + +/* Add a property node, various forms. */ +struct dt_property *dt_add_property(struct dt_node *node, + const char *name, + const void *val, size_t size); +struct dt_property *dt_add_property_string(struct dt_node *node, + const char *name, + const char *value); +struct dt_property *dt_add_property_nstr(struct dt_node *node, + const char *name, + const char *value, unsigned int vlen); + +/* Given out enough GCC extensions, we will achieve enlightenment! */ +#define dt_add_property_strings(node, name, ...) \ + __dt_add_property_strings((node), ((name)), \ + sizeof((const char *[]) { __VA_ARGS__ })/sizeof(const char *), \ + __VA_ARGS__) + +struct dt_property *__dt_add_property_strings(struct dt_node *node, + const char *name, + int count, ...); + +/* Given out enough GCC extensions, we will achieve enlightenment! */ +#define dt_add_property_cells(node, name, ...) \ + __dt_add_property_cells((node), ((name)), \ + sizeof((u32[]) { __VA_ARGS__ })/sizeof(u32), \ + __VA_ARGS__) + +struct dt_property *__dt_add_property_cells(struct dt_node *node, + const char *name, + int count, ...); + +#define dt_add_property_u64s(node, name, ...) \ + __dt_add_property_u64s((node), ((name)), \ + sizeof((u64[]) { __VA_ARGS__ })/sizeof(u64), \ + __VA_ARGS__) + +struct dt_property *__dt_add_property_u64s(struct dt_node *node, + const char *name, + int count, ...); + +static inline struct dt_property *dt_add_property_u64(struct dt_node *node, + const char *name, u64 val) +{ + return dt_add_property_cells(node, name, (u32)(val >> 32), + (u32)(val & 0xffffffffUL)); +} + +void dt_del_property(struct dt_node *node, struct dt_property *prop); + +void dt_check_del_prop(struct dt_node *node, const char *name); + +/* Warning: moves *prop! */ +void dt_resize_property(struct dt_property **prop, size_t len); + +void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val); +u32 dt_property_get_cell(const struct dt_property *prop, u32 index); +u64 dt_property_get_u64(const struct dt_property *prop, u32 index); + +/* First child of this node. */ +struct dt_node *dt_first(const struct dt_node *root); + +/* Return next node, or NULL. */ +struct dt_node *dt_next(const struct dt_node *root, const struct dt_node *prev); + +/* Iterate nodes */ +#define dt_for_each_node(root, node) \ + for (node = dt_first(root); node; node = dt_next(root, node)) + +#define dt_for_each_child(parent, node) \ + list_for_each(&parent->children, node, list) + +/* Find a string in a string list */ +bool dt_prop_find_string(const struct dt_property *p, const char *s); + +/* Check a compatible property */ +bool dt_node_is_compatible(const struct dt_node *node, const char *compat); + +/* Find a node based on compatible property */ +struct dt_node *dt_find_compatible_node(struct dt_node *root, + struct dt_node *prev, + const char *compat); + +#define dt_for_each_compatible(root, node, compat) \ + for (node = NULL; \ + (node = dt_find_compatible_node(root, node, compat)) != NULL;) + +struct dt_node *dt_find_compatible_node_on_chip(struct dt_node *root, + struct dt_node *prev, + const char *compat, + uint32_t chip_id); + +#define dt_for_each_compatible_on_chip(root, node, compat, chip_id) \ + for (node = NULL; \ + (node = dt_find_compatible_node_on_chip(root, node,\ + compat, chip_id)) != NULL;) +/* Check status property */ +bool dt_node_is_enabled(struct dt_node *node); + +/* Build the full path for a node. Return a new block of memory, caller + * shall free() it + */ +char *dt_get_path(const struct dt_node *node); + +/* Find a node by path */ +struct dt_node *dt_find_by_path(struct dt_node *root, const char *path); + +/* Find a child node by name */ +struct dt_node *dt_find_by_name(struct dt_node *root, const char *name); + +/* Find a node by phandle */ +struct dt_node *dt_find_by_phandle(struct dt_node *root, u32 phandle); + +/* Find a property by name. */ +const struct dt_property *dt_find_property(const struct dt_node *node,\ + const char *name); +const struct dt_property *dt_require_property(const struct dt_node *node, + const char *name, int wanted_len); + +/* non-const variant */ +struct dt_property *__dt_find_property(struct dt_node *node, const char *name); + +/* Find a property by name, check if it's the same as val. */ +bool dt_has_node_property(const struct dt_node *node, + const char *name, const char *val); + +/* Free a node (and any children). */ +void dt_free(struct dt_node *node); + +/* Parse an initial fdt */ +void dt_expand(const void *fdt); +int dt_expand_node(struct dt_node *node, const void *fdt, int fdt_node) __warn_unused_result; + +/* Simplified accessors */ +u64 dt_prop_get_u64(const struct dt_node *node, const char *prop); +u64 dt_prop_get_u64_def(const struct dt_node *node, const char *prop, u64 def); +u32 dt_prop_get_u32(const struct dt_node *node, const char *prop); +u32 dt_prop_get_u32_def(const struct dt_node *node, const char *prop, u32 def); +const void *dt_prop_get(const struct dt_node *node, const char *prop); +const void *dt_prop_get_def(const struct dt_node *node, const char *prop, + void *def); +const void *dt_prop_get_def_size(const struct dt_node *node, const char *prop, + void *def, size_t *len); +u32 dt_prop_get_cell(const struct dt_node *node, const char *prop, u32 cell); +u32 dt_prop_get_cell_def(const struct dt_node *node, const char *prop, u32 cell, u32 def); + +/* Parsing helpers */ +u32 dt_n_address_cells(const struct dt_node *node); +u32 dt_n_size_cells(const struct dt_node *node); +u64 dt_get_number(const void *pdata, unsigned int cells); + +/* Find an ibm,chip-id property in this node; if not found, walk up the parent + * nodes. */ +u32 dt_get_chip_id(const struct dt_node *node); + +/* Same as dt_get_chip_id except Returns -1 if no chip-id property exists. */ +u32 __dt_get_chip_id(const struct dt_node *node); + +/* Address accessors ("reg" properties parsing). No translation, + * only support "simple" address forms (1 or 2 cells). Asserts + * if address doesn't exist + */ +u64 dt_get_address(const struct dt_node *node, unsigned int index, + u64 *out_size); + +/* Count "reg" property entries */ +unsigned int dt_count_addresses(const struct dt_node *node); + +/* Address translation + * + * WARNING: Current implementation is simplified and will not + * handle complex address formats with address space indicators + * nor will it handle "ranges" translations yet... (XX TODO) + */ +u64 dt_translate_address(const struct dt_node *node, unsigned int index, + u64 *out_size); + +/* compare function used to sort child nodes by name when added to the + * tree. This is mainly here for testing. + */ +int dt_cmp_subnodes(const struct dt_node *a, const struct dt_node *b); + +struct dt_node *__dt_find_by_name_addr(struct dt_node *parent, const char *name, + const char *addr); +struct dt_node *dt_find_by_name_addr(struct dt_node *parent, const char *name, + uint64_t addr); + +/* phandle fixup helper */ +void dt_adjust_subtree_phandle(struct dt_node *subtree, + const char** (get_properties_to_fix)(struct dt_node *n)); + +#endif /* __DEVICE_H */ diff --git a/roms/skiboot/include/dio-p9.h b/roms/skiboot/include/dio-p9.h new file mode 100644 index 000000000..957322f1b --- /dev/null +++ b/roms/skiboot/include/dio-p9.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2019 IBM Corp. */ + +#ifndef __DIO_H +#define __DIO_H + +struct proc_chip; + +/* Initialize the P9 DIO */ +extern void p9_dio_init(void); + +/* The function typedef for dio interrupt callback */ +typedef void (*dio_interrupt_callback)(struct proc_chip *chip); + +/* Register dio interrupt on GPIO port. + * This effectively enables the DIO interrupt on the GPIO port, + * and callback will be called when the interrupt is triggered */ +extern int dio_interrupt_register(struct proc_chip *chip, + int port, dio_interrupt_callback c); + +/* Deregister dio interrupt on GPIO port. + * This effectively disables the DIO interrupt on the GPIO port. */ +extern int dio_interrupt_deregister(struct proc_chip *chip, + int port, dio_interrupt_callback c); + +/* The function to be called when DIO interrupt is triggered */ +extern void dio_interrupt_handler(uint32_t chip_id); + + +#define NUM_OF_P9_DIO_PORTS 3 /* P9 has GPIO port 0~2 for interrupts */ + +struct p9_dio { + dio_interrupt_callback callbacks[NUM_OF_P9_DIO_PORTS]; +}; + +#endif /* __DIO_H */ diff --git a/roms/skiboot/include/direct-controls.h b/roms/skiboot/include/direct-controls.h new file mode 100644 index 000000000..8e3809bff --- /dev/null +++ b/roms/skiboot/include/direct-controls.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __DIRECT_CONTROLS_H +#define __DIRECT_CONTROLS_H + +#include <skiboot.h> +#include <opal.h> +#include <cpu.h> + +/* fast reboot APIs */ +extern int sreset_all_prepare(void); +extern int sreset_all_others(void); +extern void sreset_all_finish(void); + +#endif /* __DIRECT_CONTROLS_H */ diff --git a/roms/skiboot/include/dts.h b/roms/skiboot/include/dts.h new file mode 100644 index 000000000..d506b71cf --- /dev/null +++ b/roms/skiboot/include/dts.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2017 IBM Corp. */ + +#ifndef __DTS_H +#define __DTS_H + +#include <stdint.h> + +extern int64_t dts_sensor_read(u32 sensor_hndl, int token, __be64 *sensor_data); +extern bool dts_sensor_create_nodes(struct dt_node *sensors); + +#endif /* __DTS_H */ diff --git a/roms/skiboot/include/elf-abi.h b/roms/skiboot/include/elf-abi.h new file mode 100644 index 000000000..29c757642 --- /dev/null +++ b/roms/skiboot/include/elf-abi.h @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __ELF_ABI_H +#define __ELF_ABI_H + +#ifndef __ASSEMBLY__ + +#if defined (_CALL_ELF) && _CALL_ELF == 2 +#define ELF_ABI_v2 +#else +#define ELF_ABI_v1 +#endif + +/* From linux/arch/powerpc/include/asm/code-patching.h */ +#define OP_RT_RA_MASK 0xffff0000UL +#define LIS_R2 0x3c020000UL +#define ADDIS_R2_R12 0x3c4c0000UL +#define ADDI_R2_R2 0x38420000UL + +static inline uint64_t function_entry_address(void *func) +{ +#ifdef ELF_ABI_v2 + u32 *insn = func; + /* + * A PPC64 ABIv2 function may have a local and a global entry + * point. We use the local entry point for branch tables called + * from asm, only a single TOC is used, so identify and step over + * the global entry point sequence. + * + * The global entry point sequence is always of the form: + * + * addis r2,r12,XXXX + * addi r2,r2,XXXX + * + * A linker optimisation may convert the addis to lis: + * + * lis r2,XXXX + * addi r2,r2,XXXX + */ + if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) || + ((*insn & OP_RT_RA_MASK) == LIS_R2)) && + ((*(insn+1) & OP_RT_RA_MASK) == ADDI_R2_R2)) + return (uint64_t)(insn + 2); + else + return (uint64_t)func; +#else + return *(uint64_t *)func; +#endif +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __COMPILER_H */ diff --git a/roms/skiboot/include/elf.h b/roms/skiboot/include/elf.h new file mode 100644 index 000000000..356c6f42f --- /dev/null +++ b/roms/skiboot/include/elf.h @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __ELF_H +#define __ELF_H + +#include <stdint.h> +#include <types.h> + +/* Generic ELF header */ +struct elf_hdr { + uint32_t ei_ident; +#if HAVE_BIG_ENDIAN +#define ELF_IDENT 0x7F454C46 +#else +#define ELF_IDENT 0x464C457F +#endif + uint8_t ei_class; +#define ELF_CLASS_32 1 +#define ELF_CLASS_64 2 + uint8_t ei_data; +#define ELF_DATA_LSB 1 +#define ELF_DATA_MSB 2 + uint8_t ei_version; + uint8_t ei_pad[9]; +}; + +#define ELF_MACH_PPC32 0x14 +#define ELF_MACH_PPC64 0x15 + +/* 64-bit ELF header */ +struct elf64be_hdr { + uint32_t ei_ident; + uint8_t ei_class; + uint8_t ei_data; + uint8_t ei_version; + uint8_t ei_pad[9]; + __be16 e_type; + __be16 e_machine; + __be32 e_version; + __be64 e_entry; + __be64 e_phoff; + __be64 e_shoff; + __be32 e_flags; + __be16 e_ehsize; + __be16 e_phentsize; + __be16 e_phnum; + __be16 e_shentsize; + __be16 e_shnum; + __be16 e_shstrndx; +}; + +/* 64-bit ELF program header */ +struct elf64be_phdr { + __be32 p_type; +#define ELF_PTYPE_LOAD 1 + __be32 p_flags; +#define ELF_PFLAGS_R 0x4 +#define ELF_PFLAGS_W 0x2 +#define ELF_PFLAGS_X 0x1 + __be64 p_offset; + __be64 p_vaddr; + __be64 p_paddr; + __be64 p_filesz; + __be64 p_memsz; + __be64 p_align; +}; + +/* 64-bit ELF section header */ +struct elf64be_shdr { + __be32 sh_name; + __be32 sh_type; + __be64 sh_flags; +#define ELF_SFLAGS_X 0x4 +#define ELF_SFLAGS_A 0x2 +#define ELF_SFLAGS_W 0x1 + __be64 sh_addr; + __be64 sh_offset; + __be64 sh_size; + __be32 sh_link; + __be32 sh_info; + __be64 sh_addralign; + __be64 sh_entsize; +}; + +/* 32-bit ELF header */ +struct elf32be_hdr { + uint32_t ei_ident; + uint8_t ei_class; + uint8_t ei_data; + uint8_t ei_version; + uint8_t ei_pad[9]; + __be16 e_type; + __be16 e_machine; + __be32 e_version; + __be32 e_entry; + __be32 e_phoff; + __be32 e_shoff; + __be32 e_flags; + __be16 e_ehsize; + __be16 e_phentsize; + __be16 e_phnum; + __be16 e_shentsize; + __be16 e_shnum; + __be16 e_shstrndx; +}; + +/* 32-bit ELF program header*/ +struct elf32be_phdr { + __be32 p_type; + __be32 p_offset; + __be32 p_vaddr; + __be32 p_paddr; + __be32 p_filesz; + __be32 p_memsz; + __be32 p_flags; + __be32 p_align; +}; + +/* 64-bit ELF header */ +struct elf64le_hdr { + uint32_t ei_ident; + uint8_t ei_class; + uint8_t ei_data; + uint8_t ei_version; + uint8_t ei_pad[9]; + __le16 e_type; + __le16 e_machine; + __le32 e_version; + __le64 e_entry; + __le64 e_phoff; + __le64 e_shoff; + __le32 e_flags; + __le16 e_ehsize; + __le16 e_phentsize; + __le16 e_phnum; + __le16 e_shentsize; + __le16 e_shnum; + __le16 e_shstrndx; +}; + +/* 64-bit ELF program header */ +struct elf64le_phdr { + __le32 p_type; +#define ELF_PTYPE_LOAD 1 + __le32 p_flags; +#define ELF_PFLAGS_R 0x4 +#define ELF_PFLAGS_W 0x2 +#define ELF_PFLAGS_X 0x1 + __le64 p_offset; + __le64 p_vaddr; + __le64 p_paddr; + __le64 p_filesz; + __le64 p_memsz; + __le64 p_align; +}; + +/* 64-bit ELF section header */ +struct elf64le_shdr { + __le32 sh_name; + __le32 sh_type; + __le64 sh_flags; +#define ELF_SFLAGS_X 0x4 +#define ELF_SFLAGS_A 0x2 +#define ELF_SFLAGS_W 0x1 + __le64 sh_addr; + __le64 sh_offset; + __le64 sh_size; + __le32 sh_link; + __le32 sh_info; + __le64 sh_addralign; + __le64 sh_entsize; +}; + +/* 32-bit ELF header */ +struct elf32le_hdr { + uint32_t ei_ident; + uint8_t ei_class; + uint8_t ei_data; + uint8_t ei_version; + uint8_t ei_pad[9]; + __le16 e_type; + __le16 e_machine; + __le32 e_version; + __le32 e_entry; + __le32 e_phoff; + __le32 e_shoff; + __le32 e_flags; + __le16 e_ehsize; + __le16 e_phentsize; + __le16 e_phnum; + __le16 e_shentsize; + __le16 e_shnum; + __le16 e_shstrndx; +}; + +/* 32-bit ELF program header*/ +struct elf32le_phdr { + __le32 p_type; + __le32 p_offset; + __le32 p_vaddr; + __le32 p_paddr; + __le32 p_filesz; + __le32 p_memsz; + __le32 p_flags; + __le32 p_align; +}; + + +/* Some relocation related stuff used in relocate.c */ +struct elf64_dyn { + int64_t d_tag; +#define DT_NULL 0 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_RELACOUNT 0x6ffffff9 + uint64_t d_val; +}; + +struct elf64_rela { + uint64_t r_offset; + uint64_t r_info; +#define ELF64_R_TYPE(info) ((info) & 0xffffffffu) + int64_t r_addend; +}; + +/* relocs we support */ +#define R_PPC64_RELATIVE 22 + + +#endif /* __ELF_H */ diff --git a/roms/skiboot/include/errorlog.h b/roms/skiboot/include/errorlog.h new file mode 100644 index 000000000..a443d3681 --- /dev/null +++ b/roms/skiboot/include/errorlog.h @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __ERRORLOG_H +#define __ERRORLOG_H + +#include <compiler.h> +#include <opal.h> +#include <stdint.h> +#include <ccan/list/list.h> + +/* Classification of error/events type reported on OPAL */ +/* Platform Events/Errors: Report Machine Check Interrupt */ +#define OPAL_PLATFORM_ERR_EVT 0x01 +/* INPUT_OUTPUT: Report all I/O related events/errors */ +#define OPAL_INPUT_OUTPUT_ERR_EVT 0x02 +/* RESOURCE_DEALLOC: Hotplug events and errors */ +#define OPAL_RESOURCE_DEALLOC_ERR_EVT 0x03 +/* MISC: Miscellaneous error */ +#define OPAL_MISC_ERR_EVT 0x04 + +/* OPAL Subsystem IDs listed for reporting events/errors */ +#define OPAL_PROCESSOR_SUBSYSTEM 0x10 +#define OPAL_MEMORY_SUBSYSTEM 0x20 +#define OPAL_IO_SUBSYSTEM 0x30 +#define OPAL_IO_DEVICES 0x40 +#define OPAL_CEC_HARDWARE 0x50 +#define OPAL_POWER_COOLING 0x60 +#define OPAL_MISC_SUBSYSTEM 0x70 +#define OPAL_SURVEILLANCE_ERR 0x7A +#define OPAL_PLATFORM_FIRMWARE 0x80 +#define OPAL_SOFTWARE 0x90 +#define OPAL_EXTERNAL_ENV 0xA0 + +/* + * During reporting an event/error the following represents + * how serious the logged event/error is. (Severity) + */ +#define OPAL_INFO 0x00 +#define OPAL_RECOVERED_ERR_GENERAL 0x10 + +/* 0x2X series is to denote set of Predictive Error */ +/* 0x20 Generic predictive error */ +#define OPAL_PREDICTIVE_ERR_GENERAL 0x20 +/* 0x21 Predictive error, degraded performance */ +#define OPAL_PREDICTIVE_ERR_DEGRADED_PERF 0x21 +/* 0x22 Predictive error, fault may be corrected after reboot */ +#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT 0x22 +/* + * 0x23 Predictive error, fault may be corrected after reboot, + * degraded performance + */ +#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_BOOT_DEGRADE_PERF 0x23 +/* 0x24 Predictive error, loss of redundancy */ +#define OPAL_PREDICTIVE_ERR_LOSS_OF_REDUNDANCY 0x24 + +/* 0x4X series for Unrecoverable Error */ +/* 0x40 Generic Unrecoverable error */ +#define OPAL_UNRECOVERABLE_ERR_GENERAL 0x40 +/* 0x41 Unrecoverable error bypassed with degraded performance */ +#define OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF 0x41 +/* 0x44 Unrecoverable error bypassed with loss of redundancy */ +#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY 0x44 +/* 0x45 Unrecoverable error bypassed with loss of redundancy and performance */ +#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY_PERF 0x45 +/* 0x48 Unrecoverable error bypassed with loss of function */ +#define OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION 0x48 +/* 0x50 In case of PANIC */ +#define OPAL_ERROR_PANIC 0x50 + +/* + * OPAL Event Sub-type + * This field provides additional information on the non-error + * event type + */ +#define OPAL_NA 0x00 +#define OPAL_MISCELLANEOUS_INFO_ONLY 0x01 +#define OPAL_PREV_REPORTED_ERR_RECTIFIED 0x10 +#define OPAL_SYS_RESOURCES_DECONFIG_BY_USER 0x20 +#define OPAL_SYS_RESOURCE_DECONFIG_PRIOR_ERR 0x21 +#define OPAL_RESOURCE_DEALLOC_EVENT_NOTIFY 0x22 +#define OPAL_CONCURRENT_MAINTENANCE_EVENT 0x40 +#define OPAL_CAPACITY_UPGRADE_EVENT 0x60 +#define OPAL_RESOURCE_SPARING_EVENT 0x70 +#define OPAL_DYNAMIC_RECONFIG_EVENT 0x80 +#define OPAL_NORMAL_SYS_PLATFORM_SHUTDOWN 0xD0 +#define OPAL_ABNORMAL_POWER_OFF 0xE0 + +/* Max user dump size is 14K */ +#define OPAL_LOG_MAX_DUMP 14336 + +/* Origin of error, elog_origin */ +#define ORG_SAPPHIRE 1 +#define ORG_POWERNV 2 + +/* Multiple user data sections */ +struct elog_user_data_section { + __be32 tag; + __be16 size; + __be16 component_id; + char data_dump[1]; +} __packed; + +/* + * All the information regarding an error/event to be reported + * needs to populate this structure using pre-defined interfaces + * only + */ +struct errorlog { + + uint16_t component_id; + uint8_t error_event_type; + uint8_t subsystem_id; + + uint8_t event_severity; + uint8_t event_subtype; + uint8_t user_section_count; + uint8_t elog_origin; + + uint32_t user_section_size; + uint32_t reason_code; + uint32_t additional_info[4]; + + uint32_t plid; + uint32_t log_size; + uint64_t elog_timeout; + + char user_data_dump[OPAL_LOG_MAX_DUMP]; + struct list_node link; +}; + +struct opal_err_info { + uint32_t reason_code; + uint8_t err_type; + uint16_t cmp_id; + uint8_t subsystem; + uint8_t sev; + uint8_t event_subtype; +}; + +/* Component IDs */ +/* In PEL error log format, Creator ID is hypervisor + * But we can have various component ID to distinguish + * which component in hypervisor is reporting the error + * This is 2 bytes long, + * first byte corresponds to Component IDs + * Second byte is reserved for the Reason code. + * Component ID is mapped to readable 4-digit ascii + * character name in FSP and displayed. + */ +/* SAPPHIRE components */ +#define OPAL_CODEUPDATE 0x4355 /* CU */ +#define OPAL_CONSOLE 0x434E /* CN */ +#define OPAL_CEC 0x4345 /* CE */ +#define OPAL_CHIP 0x4348 /* CH */ +#define OPAL_ELOG 0x454C /* EL */ +#define OPAL_NVRAM 0x4E56 /* NV */ +#define OPAL_RTC 0x5254 /* RT */ +#define OPAL_SURVEILLANCE 0x5355 /* SU */ +#define OPAL_SYSPARAM 0x5350 /* SP */ +#define OPAL_LPC 0x4C50 /* LP */ +#define OPAL_UART 0x5541 /* UA */ +#define OPAL_OCC 0x4F43 /* OC */ +#define OPAL_OP_PANEL 0x4F50 /* OP */ +#define OPAL_PHB 0x5048 /* PH */ +#define OPAL_PSI 0x5053 /* PS */ +#define OPAL_VPD 0x5650 /* VP */ +#define OPAL_XSCOM 0x5853 /* XS */ +#define OPAL_PCI 0x5043 /* PC */ +#define OPAL_MISC 0x4D49 /* MI */ +#define OPAL_ATTN 0x4154 /* AT */ +#define OPAL_MEM_ERR 0x4D45 /* ME */ +#define OPAL_CENTAUR 0x4354 /* CT */ +#define OPAL_MFSI 0x4D46 /* MF */ +#define OPAL_DUMP 0x4455 /* DU */ +#define OPAL_LED 0x4C45 /* LE */ +#define OPAL_SENSOR 0x5345 /* SE */ +#define OPAL_SLW 0x534C /* SL */ +#define OPAL_FSP 0x4650 /* FP */ +#define OPAL_I2C 0x4943 /* IC */ +#define OPAL_IPMI 0x4950 /* IP */ + +/* SAPPHIRE SRC component ID*/ +#define OPAL_SRC_COMPONENT_CODE_UPDATE 0x1000 +#define OPAL_SRC_COMPONENT_XSCOM 0x1100 +#define OPAL_SRC_COMPONENT_PCI 0x1200 +#define OPAL_SRC_COMPONENT_MISC 0x1300 +#define OPAL_SRC_COMPONENT_ATTN 0x1400 +#define OPAL_SRC_COMPONENT_MEM_ERR 0x1500 +#define OPAL_SRC_COMPONENT_CENTAUR 0x1600 +#define OPAL_SRC_COMPONENT_MFSI 0x1700 +#define OPAL_SRC_COMPONENT_DUMP 0x1800 +#define OPAL_SRC_COMPONENT_LED 0x1900 +#define OPAL_SRC_COMPONENT_VPD 0x1a00 +#define OPAL_SRC_COMPONENT_CONSOLE 0x1b00 +#define OPAL_SRC_COMPONENT_SENSOR 0x2000 +#define OPAL_SRC_COMPONENT_SLW 0x2100 +#define OPAL_SRC_COMPONENT_FSP 0x2200 +#define OPAL_SRC_COMPONENT_I2C 0x2300 +#define OPAL_SRC_COMPONENT_IPMI 0x2400 +#define OPAL_SRC_COMPONENT_CEC 0x3000 +#define OPAL_SRC_COMPONENT_CHIP 0x4000 +#define OPAL_SRC_COMPONENT_ELOG 0x5000 +#define OPAL_SRC_COMPONENT_NVRAM 0x6000 +#define OPAL_SRC_COMPONENT_RTC 0x7000 +#define OPAL_SRC_COMPONENT_SURVEILLANCE 0x8000 +#define OPAL_SRC_COMPONENT_SYSPARAM 0x9000 +#define OPAL_SRC_COMPONENT_LPC 0xa000 +#define OPAL_SRC_COMPONENT_UART 0xb000 +#define OPAL_SRC_COMPONENT_OCC 0xc000 +#define OPAL_SRC_COMPONENT_OP_PANEL 0xd000 +#define OPAL_SRC_COMPONENT_PHB 0xe000 +#define OPAL_SRC_COMPONENT_PSI 0xf000 + +enum opal_reasoncode { +/* code update */ + OPAL_RC_CU_FLASH = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x10, + OPAL_RC_CU_INIT = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x11, + OPAL_RC_CU_SG_LIST = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x12, + OPAL_RC_CU_COMMIT = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x13, + OPAL_RC_CU_MSG = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x14, + OPAL_RC_CU_NOTIFY = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x15, + OPAL_RC_CU_MARKER_LID = OPAL_SRC_COMPONENT_CODE_UPDATE | 0x16, +/* NVRAM */ + OPAL_RC_NVRAM_INIT = OPAL_SRC_COMPONENT_NVRAM | 0x10, + OPAL_RC_NVRAM_OPEN = OPAL_SRC_COMPONENT_NVRAM | 0x11, + OPAL_RC_NVRAM_SIZE = OPAL_SRC_COMPONENT_NVRAM | 0x12, + OPAL_RC_NVRAM_WRITE = OPAL_SRC_COMPONENT_NVRAM | 0x13, + OPAL_RC_NVRAM_READ = OPAL_SRC_COMPONENT_NVRAM | 0x14, +/* CENTAUR */ + OPAL_RC_CENTAUR_INIT = OPAL_SRC_COMPONENT_CENTAUR | 0x10, + OPAL_RC_CENTAUR_RW_ERR = OPAL_SRC_COMPONENT_CENTAUR | 0x11, +/* MFSI */ + OPAL_RC_MFSI_RW_ERR = OPAL_SRC_COMPONENT_MFSI | 0x10, +/* UART */ + OPAL_RC_UART_INIT = OPAL_SRC_COMPONENT_UART | 0x10, +/* OCC */ + OPAL_RC_OCC_RESET = OPAL_SRC_COMPONENT_OCC | 0x10, + OPAL_RC_OCC_LOAD = OPAL_SRC_COMPONENT_OCC | 0x11, + OPAL_RC_OCC_PSTATE_INIT = OPAL_SRC_COMPONENT_OCC | 0x12, + OPAL_RC_OCC_TIMEOUT = OPAL_SRC_COMPONENT_OCC | 0x13, +/* RTC */ + OPAL_RC_RTC_READ = OPAL_SRC_COMPONENT_RTC | 0x10, + OPAL_RC_RTC_TOD = OPAL_SRC_COMPONENT_RTC | 0x11, +/* SURVEILLANCE */ + OPAL_RC_SURVE_INIT = OPAL_SRC_COMPONENT_SURVEILLANCE | 0x10, + OPAL_RC_SURVE_STATUS = OPAL_SRC_COMPONENT_SURVEILLANCE | 0x11, + OPAL_RC_SURVE_ACK = OPAL_SRC_COMPONENT_SURVEILLANCE | 0x12, + OPAL_INJECTED_HIR = OPAL_SRC_COMPONENT_SURVEILLANCE | 0x13, +/* SYSPARAM */ + OPAL_RC_SYSPARM_INIT = OPAL_SRC_COMPONENT_SYSPARAM | 0x10, + OPAL_RC_SYSPARM_MSG = OPAL_SRC_COMPONENT_SYSPARAM | 0x11, +/* LPC */ + OPAL_RC_LPC_READ = OPAL_SRC_COMPONENT_LPC | 0x10, + OPAL_RC_LPC_WRITE = OPAL_SRC_COMPONENT_LPC | 0x11, + OPAL_RC_LPC_SYNC = OPAL_SRC_COMPONENT_LPC | 0x12, + OPAL_RC_LPC_SYNC_PERF = OPAL_SRC_COMPONENT_LPC | 0x13, +/* OP_PANEL */ + OPAL_RC_PANEL_WRITE = OPAL_SRC_COMPONENT_OP_PANEL | 0x10, +/* PSI */ + OPAL_RC_PSI_INIT = OPAL_SRC_COMPONENT_PSI | 0x10, + OPAL_RC_PSI_IRQ_RESET = OPAL_SRC_COMPONENT_PSI | 0x11, + OPAL_RC_PSI_TIMEOUT = OPAL_SRC_COMPONENT_PSI | 0X12, +/* XSCOM */ + OPAL_RC_XSCOM_RW = OPAL_SRC_COMPONENT_XSCOM | 0x10, + OPAL_RC_XSCOM_INDIRECT_RW = OPAL_SRC_COMPONENT_XSCOM | 0x11, + OPAL_RC_XSCOM_RESET = OPAL_SRC_COMPONENT_XSCOM | 0x12, + OPAL_RC_XSCOM_BUSY = OPAL_SRC_COMPONENT_XSCOM | 0x13, +/* PCI */ + OPAL_RC_PCI_INIT_SLOT = OPAL_SRC_COMPONENT_PCI | 0x10, + OPAL_RC_PCI_ADD_SLOT = OPAL_SRC_COMPONENT_PCI | 0x11, + OPAL_RC_PCI_SCAN = OPAL_SRC_COMPONENT_PCI | 0x12, + OPAL_RC_PCI_RESET_PHB = OPAL_SRC_COMPONENT_PCI | 0x10, +/* ATTN */ + OPAL_RC_ATTN = OPAL_SRC_COMPONENT_ATTN | 0x10, +/* MEM_ERR */ + OPAL_RC_MEM_ERR_RES = OPAL_SRC_COMPONENT_MEM_ERR | 0x10, + OPAL_RC_MEM_ERR_DEALLOC = OPAL_SRC_COMPONENT_MEM_ERR | 0x11, +/* DUMP */ + OPAL_RC_DUMP_INIT = OPAL_SRC_COMPONENT_DUMP | 0x10, + OPAL_RC_DUMP_LIST = OPAL_SRC_COMPONENT_DUMP | 0x11, + OPAL_RC_DUMP_ACK = OPAL_SRC_COMPONENT_DUMP | 0x12, + OPAL_RC_DUMP_MDST_INIT = OPAL_SRC_COMPONENT_DUMP | 0x13, + OPAL_RC_DUMP_MDST_UPDATE = OPAL_SRC_COMPONENT_DUMP | 0x14, + OPAL_RC_DUMP_MDST_ADD = OPAL_SRC_COMPONENT_DUMP | 0x15, + OPAL_RC_DUMP_MDST_REMOVE = OPAL_SRC_COMPONENT_DUMP | 0x16, +/* LED */ + OPAL_RC_LED_SPCN = OPAL_SRC_COMPONENT_LED | 0x10, + OPAL_RC_LED_BUFF = OPAL_SRC_COMPONENT_LED | 0x11, + OPAL_RC_LED_LC = OPAL_SRC_COMPONENT_LED | 0x12, + OPAL_RC_LED_STATE = OPAL_SRC_COMPONENT_LED | 0x13, + OPAL_RC_LED_SUPPORT = OPAL_SRC_COMPONENT_LED | 0x14, +/* SENSOR */ + OPAL_RC_SENSOR_INIT = OPAL_SRC_COMPONENT_SENSOR | 0x10, + OPAL_RC_SENSOR_READ = OPAL_SRC_COMPONENT_SENSOR | 0x11, + OPAL_RC_SENSOR_ASYNC_COMPLETE + = OPAL_SRC_COMPONENT_SENSOR | 0x12, +/* SLW */ + OPAL_RC_SLW_INIT = OPAL_SRC_COMPONENT_SLW | 0x10, + OPAL_RC_SLW_SET = OPAL_SRC_COMPONENT_SLW | 0x11, + OPAL_RC_SLW_GET = OPAL_SRC_COMPONENT_SLW | 0x12, + OPAL_RC_SLW_REG = OPAL_SRC_COMPONENT_SLW | 0x13, +/* FSP */ + OPAL_RC_FSP_POLL_TIMEOUT = OPAL_SRC_COMPONENT_FSP | 0x10, + OPAL_RC_FSP_MBOX_ERR = OPAL_SRC_COMPONENT_FSP | 0x11, + OPAL_RC_FSP_DISR_HIR_MASK = OPAL_SRC_COMPONENT_FSP | 0x12, +/* I2C */ + OPAL_RC_I2C_INIT = OPAL_SRC_COMPONENT_I2C | 0X10, + OPAL_RC_I2C_START_REQ = OPAL_SRC_COMPONENT_I2C | 0X11, + OPAL_RC_I2C_TIMEOUT = OPAL_SRC_COMPONENT_I2C | 0x12, + OPAL_RC_I2C_TRANSFER = OPAL_SRC_COMPONENT_I2C | 0x13, + OPAL_RC_I2C_RESET = OPAL_SRC_COMPONENT_I2C | 0x14, + +/* IPMI */ + OPAL_RC_IPMI_REQ = OPAL_SRC_COMPONENT_IPMI | 0x10, + OPAL_RC_IPMI_RESP = OPAL_SRC_COMPONENT_IPMI | 0x11, + OPAL_RC_IPMI_DMA_ERROR_RESP + = OPAL_SRC_COMPONENT_IPMI | 0x12, + +/* Platform error */ + OPAL_RC_ABNORMAL_REBOOT = OPAL_SRC_COMPONENT_CEC | 0x10, + +/* FSP console */ + OPAL_RC_CONSOLE_HANG = OPAL_SRC_COMPONENT_CONSOLE | 0x10, +}; + +#define OPAL_ELOG_SEC_DESC 0x44455343 + +#define DEFINE_LOG_ENTRY(reason, type, id, subsys, \ +severity, subtype) static struct opal_err_info err_##reason = \ +{ .reason_code = reason, .err_type = type, .cmp_id = id, \ +.subsystem = subsys, .sev = severity, .event_subtype = subtype } + +/* This is wrapper around the error log function, which creates + * and commits the error to FSP. + * Used for simple error logging. + * Returns a Log ID, if an error involves a service processor needing + * to be kicked, this logid can be sent to the service processor explaining + * *why* we kicked it. Log Id = -1 on error. + */ +uint32_t log_simple_error(struct opal_err_info *e_info, + const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); + +#define e_info(reason_code) err_##reason_code + +struct errorlog *opal_elog_create(struct opal_err_info *e_info, + uint32_t tag) __warn_unused_result; +void log_add_section(struct errorlog *buf, uint32_t tag); +void log_append_data(struct errorlog *buf, unsigned char *data, uint16_t size); +void log_append_msg(struct errorlog *buf, + const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +void log_commit(struct errorlog *elog); + +/* Called by the backend after an error has been logged by the + * backend. If the error could not be logged successfully success is + * set to false. */ +void opal_elog_complete(struct errorlog *elog, bool success); + +int elog_init(void); + +#endif /* __ERRORLOG_H */ diff --git a/roms/skiboot/include/fsi-master.h b/roms/skiboot/include/fsi-master.h new file mode 100644 index 000000000..df4ca877d --- /dev/null +++ b/roms/skiboot/include/fsi-master.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2014 IBM Corp. */ + +#ifndef __FSI_MASTER_H +#define __FSI_MASTER_H + +/* + * Definition of the MFSI masters + */ +#define MFSI_cMFSI0 0 +#define MFSI_cMFSI1 1 +#define MFSI_hMFSI0 2 + +extern int64_t mfsi_read(uint32_t chip, uint32_t mfsi, uint32_t port, + uint32_t fsi_addr, uint32_t *data); + +extern int64_t mfsi_write(uint32_t chip, uint32_t mfsi, uint32_t port, + uint32_t fsi_addr, uint32_t data); + +extern void mfsi_init(void); + +#endif /* __FSI_MASTER_H */ + diff --git a/roms/skiboot/include/fsp-attn.h b/roms/skiboot/include/fsp-attn.h new file mode 100644 index 000000000..76c33221e --- /dev/null +++ b/roms/skiboot/include/fsp-attn.h @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __FSP_ATTN_H +#define __FSP_ATTN_H + +/* Per spec attn area can go up to 0x400 bytes */ +#define ATTN_AREA_SZ 0x400 + +extern struct sp_attn_area cpu_ctl_sp_attn_area1; +extern struct sp_attn_area cpu_ctl_sp_attn_area2; + +struct spat_entry { + /* Virtual address */ + __be64 vaddr; + /* Partition id */ + __be16 id; + uint8_t reserved[6]; +} __packed; + +/* SP Address Table: Structure is not used as of today, defined to + * keep in sync with the spec */ +struct sp_addr_table { + /* Index of last valid spat entry */ + __be32 idx; + /* Number of SPAT entries allocated = 31 for SP */ + __be32 count; + uint8_t reserved1[8]; + /* SPAT entries */ + struct spat_entry spat_entry[31]; +} __packed; + +/* SP Attention Areas */ +struct sp_attn_area { + /* Processor Number */ + uint8_t processor; + /* Attention command */ + uint8_t attn_cmd; + __be16 data_len; + uint8_t data[]; +} __packed __align(ATTN_AREA_SZ); + +#define SRC_WORD_COUNT 8 +#define SRC_LEN 32 +/* Max limit of user data size is 940 (due to attention area size) */ +#define TI_MSG_LEN 940 + +/* Maximum sapphire version length (approx) */ +#define VERSION_LEN 80 +/* Up to 10 frames each of length 40 bytes + header = 430 bytes */ +#define BT_FRAME_LEN 430 +/* File info length : Use the rest of the memory for file details */ +#define FILE_INFO_LEN (TI_MSG_LEN - VERSION_LEN - BT_FRAME_LEN) + +struct user_data { + char version[VERSION_LEN]; + char bt_buf[BT_FRAME_LEN]; + char file_info[FILE_INFO_LEN]; +} __packed; + +/* Terminate Immediate Attention */ +struct ti_attn { + /* Command valid */ + uint8_t cmd_valid; + /* Attention command */ + uint8_t attn_cmd; + __be16 data_len; + /* Controls dump actions */ + uint8_t dump_ctrl; + uint8_t reserved1; + /* Hardware dump type */ + __be16 dump_type; + /* SRC format */ + uint8_t src_fmt; + /* SRC flags */ + uint8_t src_flags; + /* Number of ASCII words */ + uint8_t ascii_cnt; + /* Number of HEX words */ + uint8_t hex_cnt; + __be16 reserved2; + /* SRC length */ + __be16 src_len; + __be32 src_word[SRC_WORD_COUNT]; + /* ASCII data */ + char src[SRC_LEN]; + __be32 msg_len; + /* User data: Debug details */ + struct user_data msg; +} __packed __align(ATTN_AREA_SZ); + +/* Hypervisor Service Routine Data area: Structure is not used as of today, + * defined to keep in sync with the spec */ +struct hsr_data_area { + /* MS Address Compare Address */ + __be64 ms_cmp_addr; + /* MS Address Compare Op (set/reset) */ + __be16 ms_cmp_op; + /* MS Address Compare Length */ + __be16 ms_cmp_len; + /* MS Address Compare Data */ + __be32 ms_cmp_data; + /* MS Address Compare Service Routine */ + __be64 ms_cmp_sr; + /* Pointer to MS Display / Alter HSR */ + __be64 ms_display; + __be64 reserved1; + /* MS Dump HSR */ + __be64 ms_dump_hsr; + /* Pointer to Real Address Validation HSR */ + __be64 hsr_raddr; + /* Effective Address Field */ + __be64 eaddr; + /* Pointer to CPU Spin HSR */ + __be64 hsr_cpu_spin; + /* Pointer to SP Glue HSR */ + __be64 hsr_sp_glue; + uint8_t reserved2[19]; + /* Time Base Flags + * bit 7 (0x01) = 0b1: hardware time base disabled + * other bits reserved + */ + uint8_t time_flags; + uint8_t reserved3[12]; + /* TDE Addr Parm */ + __be64 tde_addr; + /* SDR1 Shared Processor HSR */ + __be64 hsr_sdr1_proc; + __be64 partition_id; + uint8_t reserved4[12]; + /* Address Type for Compare + * 1 = real address + * 2 = effective address + * 3 = virtual address + */ + __be16 ms_addr_type; + uint8_t reserved5[10]; + /* Cache Flush Service Routine Pointer */ + __be64 cfsr; + uint8_t reserved6[88]; +} __packed; + +#endif /* __FSP_ATTN_H */ diff --git a/roms/skiboot/include/fsp-elog.h b/roms/skiboot/include/fsp-elog.h new file mode 100644 index 000000000..11d1154d9 --- /dev/null +++ b/roms/skiboot/include/fsp-elog.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#include <opal.h> +#include <errorlog.h> +#include <pel.h> +#ifndef __ELOG_H +#define __ELOG_H + +#define ELOG_TYPE_PEL 0 +#define MAX_RETRIES 3 + +/* Following variables are used to indicate state of the + * head log entry which is being fetched from FSP/OPAL and + * these variables are not overwritten until next log is + * retrieved from FSP/OPAL. + */ +enum elog_head_state { + ELOG_STATE_FETCHING, /*In the process of reading log from FSP. */ + ELOG_STATE_FETCHED_DATA,/* Indicates reading log is completed */ + ELOG_STATE_HOST_INFO, /* Host read log info */ + ELOG_STATE_NONE, /* Indicates to fetch next log */ + ELOG_STATE_REJECTED, /* resend all pending logs to linux */ +}; + +/* Generate src from opal reason code (src_comp) */ +#define generate_src_from_comp(src_comp) (OPAL_SRC_TYPE_ERROR << 24 | \ + OPAL_FAILING_SUBSYSTEM << 16 | src_comp) + +int elog_fsp_commit(struct errorlog *buf) __warn_unused_result; + +bool opal_elog_info(__be64 *opal_elog_id, __be64 *opal_elog_size) __warn_unused_result; + +bool opal_elog_read(void *buffer, uint64_t opal_elog_size, + uint64_t opal_elog_id) __warn_unused_result; + +bool opal_elog_ack(uint64_t ack_id) __warn_unused_result; + +void opal_resend_pending_logs(void); + +void elog_set_head_state(bool opal_logs, enum elog_head_state state); + +#endif /* __ELOG_H */ diff --git a/roms/skiboot/include/fsp-leds.h b/roms/skiboot/include/fsp-leds.h new file mode 100644 index 000000000..499e477d6 --- /dev/null +++ b/roms/skiboot/include/fsp-leds.h @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * SPCN based LED location code and other information + * + * Copyright 2013-2016 IBM Corp. + */ + +#ifndef __FSP_LEDS_H +#define __FSP_LEDS_H + +/* Supported FSP response codes */ +#define FSP_IND_NOT_IMPLMNTD 0x00 /* Indicator not implemented */ +#define FSP_IND_IMPLMNTD 0x04 /* Indicator implemented */ +#define FSP_IND_IMPL_UNKNOWN 0x08 /* Implementation unknown */ +#define FSP_IND_INACTIVE 0x00 /* Indicator not active */ +#define FSP_IND_IDENTIFY_ACTV 0x01 /* Identify state active */ +#define FSP_IND_FAULT_ACTV 0x02 /* Fault state active */ +#define FSP_IND_STATE_UNKNOWN 0xff /* Indicator state unknown */ +#define FSP_RSRC_NOT_PRESENT 0x00 /* Resource not present */ +#define FSP_RSRC_PRESENT 0x40 /* Resource present */ +#define FSP_RSRC_PRSNC_UNKNOWN 0x80 /* Resource presence unknown */ + +/* LED exclusive bits */ +#define FSP_LED_EXCL_FAULT (1UL << 0) +#define FSP_LED_EXCL_IDENTIFY (1UL << 1) + +/* LED update message source */ +enum spcn_cmd_src { + SPCN_SRC_FSP = 0, + SPCN_SRC_OPAL = 1, + SPCN_SRC_MAX = 2 +}; + +/* SPCN set LED */ +struct spcn_led_data { + u8 lc_len; + __be16 state; + char lc_code[LOC_CODE_SIZE]; +} __packed; + +/* LED data */ +struct fsp_led_data { + u16 rid; /* Resource ID */ + u8 lc_len; /* Location code len */ + char loc_code[LOC_CODE_SIZE]; + u16 parms; /* Parameters */ + u16 status; /* Status */ + u16 excl_bit; /* Exclusive LED bit */ + struct list_node link; +}; + +/* FSP location code request */ +struct fsp_loc_code_req { + __be16 len; + __be16 req_type; + u8 raw_len; + u8 lc_sz; + char loc_code[LOC_CODE_SIZE]; +} __packed; + +/* FSP location code data */ +struct fsp_loc_code_data { + __be16 size; + __be32 ccin; + u8 status; + u8 ind_state; + u8 raw_len; + u8 fld_sz; + + /* The size below must include the padding to + * make the whole structure aligned to a + * multiple of 4 bytes + */ + char loc_code[LOC_CODE_SIZE + 2]; /* 82 */ + + /* We need to pack the structure otherwise the + * compiler adds additional alignment to make + * it 8 bytes aligned + */ +} __packed; + +/* Get indicator state request */ +struct fsp_get_ind_state_req { + __be16 size; + u8 lc_len; + u8 fld_sz; + char loc_code[LOC_CODE_SIZE]; +} __packed; + +/* Set indicator state request */ +struct fsp_set_ind_state_req { + __be16 size; + __be16 req_type; + u8 reserved[3]; + u8 ind_state; + u8 lc_len; + u8 fld_sz; + char loc_code[LOC_CODE_SIZE]; +} __packed; + +/* LED set SPCN command */ +struct led_set_cmd { + char loc_code[LOC_CODE_SIZE]; + u8 command; + u8 state; + u16 ckpt_status; /* Checkpointed status */ + u16 ckpt_excl_bit; /* Checkpointed exclusive status */ + u64 async_token; /* OPAL async token */ + enum spcn_cmd_src cmd_src; /* OPAL or FSP based */ + struct list_node link; +}; + +/* System Attention Indicator */ +struct sai_data { + uint8_t state; + char loc_code[LOC_CODE_SIZE]; +}; + +/* LED commands and state */ +#define LED_COMMAND_FAULT 1 +#define LED_COMMAND_IDENTIFY 0 +#define LED_STATE_ON 1 +#define LED_STATE_OFF 0 + +/* FSP get loc-code list command request type */ +#define GET_LC_CMPLT_SYS 0x8000 +#define GET_LC_ENCLOSURES 0x4000 +#define GET_LC_ENCL_DESCENDANTS 0x2000 +#define GET_LC_SINGLE_LOC_CODE 0x0100 + +/* FSP set indicator command request type */ +#define SET_IND_ENCLOSURE 0x4000 +#define SET_IND_SINGLE_LOC_CODE 0x0001 + +/* Response buffer */ +#define OUTBUF_HEADER_SIZE 8 + +/* LED miscellaneous */ +#define LOC_CODE_LEN 1 +#define LED_CONTROL_LEN 2 +#define FSP_LC_STRUCT_FIXED_SZ 0x0a + +/* LED Device tree property names */ +#define DT_PROPERTY_LED_COMPATIBLE "ibm,opal-v3-led" +#define DT_PROPERTY_LED_NODE "leds" +#define DT_PROPERTY_LED_MODE "led-mode" +#define DT_PROPERTY_LED_TYPES "led-types" + +/* LED Mode */ +#define LED_MODE_LIGHT_PATH "lightpath" +#define LED_MODE_GUIDING_LIGHT "guidinglight" + +/* LED type */ +#define LED_TYPE_IDENTIFY "identify" +#define LED_TYPE_FAULT "fault" +#define LED_TYPE_ATTENTION "attention" + +#endif diff --git a/roms/skiboot/include/fsp-sysparam.h b/roms/skiboot/include/fsp-sysparam.h new file mode 100644 index 000000000..b1182f7bc --- /dev/null +++ b/roms/skiboot/include/fsp-sysparam.h @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __FSP_SYSPARAM_H +#define __FSP_SYSPARAM_H + +/* System parameter numbers used in the protocol + * + * these are the only ones we care about right now + */ +#define SYS_PARAM_SURV 0xf0000001 +#define SYS_PARAM_HMC_MANAGED 0xf0000003 +#define SYS_PARAM_FW_IPL_SIDE 0xf0000007 +#define SYS_PARAM_FLASH_POLICY 0xf0000012 +#define SYS_PARAM_NEED_HMC 0xf0000016 +#define SYS_PARAM_REAL_SAI 0xf0000019 +#define SYS_PARAM_PARTITION_SAI 0xf000001A +#define SYS_PARAM_PLAT_SAI 0xf000001B +#define SYS_PARAM_FW_LICENSE 0xf000001d +#define SYS_PARAM_WWPN 0xf0000023 +#define SYS_PARAM_DEF_BOOT_DEV 0xf0000024 +#define SYS_PARAM_NEXT_BOOT_DEV 0xf0000025 +#define SYS_PARAM_CONSOLE_SELECT 0xf0000026 +#define SYS_PARAM_BOOT_DEV_PATH 0xf0000027 + + +/* Completion for a sysparam call. err_len is either a negative error + * code or the positive length of the returned data + */ +typedef void (*sysparam_compl_t)(uint32_t param_id, int err_len, void *data); + + +/* Send a sysparam query request. Operation can be synchronous or + * asynchronous: + * + * - synchronous (async_complete is NULL), the result code is either + * a negative error code or a positive returned length. + * + * - asynchronous (async_complete non NULL). The result code is 0 for + * successfully queued request or an error for an immediate error. + * A successfully queued request will complete via the completion + * callback defined above + */ +int fsp_get_sys_param(uint32_t param_id, void *buffer, uint32_t length, + sysparam_compl_t async_complete, void *comp_data); + + +void fsp_sysparam_init(void); + +/* + * System parameter update notification. + * param_id : parameter id + * len : length of data + * data : pointer to data + */ +typedef bool (*sysparam_update_notify)(struct fsp_msg *msg); + +/* Register/unregister for system parameter update notifier chain */ +void sysparam_add_update_notifier(sysparam_update_notify notify); +void sysparam_del_update_notifier(sysparam_update_notify notify); + +#endif /* __FSP_SYSPARAM_H */ diff --git a/roms/skiboot/include/fsp.h b/roms/skiboot/include/fsp.h new file mode 100644 index 000000000..2010dd0f0 --- /dev/null +++ b/roms/skiboot/include/fsp.h @@ -0,0 +1,855 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * IBM System P FSP (Flexible Service Processor) + * + * Copyright 2013-2019 IBM Corp. + */ + +#ifndef __FSP_H +#define __FSP_H + +#include <skiboot.h> +#include <psi.h> + +/* Current max number of FSPs + * one primary and one secondary is all we support + */ +#define FSP_MAX 2 + +/* Command protocol. + * + * Commands have a byte class and a byte subcommand. With the exception + * of some HMC related commands (class 0xe0) which we don't support, + * only one outstanding command is allowed for a given class. + * + * Note: 0xCE and 0xCF fall into the same class, ie, only one of them can + * be outstanding. + * + * A command is outstanding until it has been acknowledged. This doesn't + * imply a response, the response can come later. + */ + +/* Protocol status error codes used by the protocol */ +#define FSP_STATUS_SUCCESS 0x00 /* Command successful */ +#define FSP_STATUS_MORE_DATA 0x02 /* Success, EOF not reached */ +#define FSP_STATUS_DATA_INLINE 0x11 /* Data inline in mbox */ +#define FSP_STATUS_INVALID_SUBCMD 0x20 +#define FSP_STATUS_INVALID_MOD 0x21 +#define FSP_STATUS_INVALID_DATA 0x22 +#define FSP_STATUS_INVALID_DPOSTATE 0x23 +#define FSP_STATUS_DMA_ERROR 0x24 +#define FSP_STATUS_INVALID_CMD 0x2c +#define FSP_STATUS_SEQ_ERROR 0x2d +#define FSP_STATUS_BAD_STATE 0x2e +#define FSP_STATUS_NOT_SUPPORTED 0x2f +#define FSP_STATUS_FILE_TOO_LARGE 0x43 +#define FSP_STATUS_FLASH_INPROGRESS 0x61 +#define FSP_STATUS_FLASH_NOPROGRESS 0x62 +#define FSP_STATUS_FLASH_INVALID_SIDE 0x63 +#define FSP_STATUS_EOF_ERROR 0x02 +#define FSP_STATUS_DMA_ERROR 0x24 +#define FSP_STATUS_BUSY 0x3e +#define FSP_STATUS_FLASH_BUSY 0x3f +#define FSP_STATUS_INVALID_SUBID 0x41 +#define FSP_STATUS_LENGTH_ERROR 0x42 +#define FSP_STAUS_INVALID_HMC_ID 0x51 +#define FSP_STATUS_SPCN_ERROR 0xA8 /* SPCN error */ +#define FSP_STATUS_INVALID_LC 0xC0 /* Invalid location code */ +#define FSP_STATUS_ENCL_IND_RESET 0xC2 /* Enclosure Indicator cannot be reset */ +#define FSP_STATUS_TOD_RESET 0xA9 /* TOD reset due to invalid state at POR */ +#define FSP_STATUS_TOD_PERMANENT_ERROR 0xAF /* Permanent error in TOD */ +#define FSP_STATUS_I2C_TRANS_ERROR 0xE4 /* I2C device / transmission error */ +#define FSP_STATUS_IND_PARTIAL_SUCCESS 0xE5 /* Indicator partial success */ +#define FSP_STATUS_GENERIC_ERROR 0xFE /* Generic Failure in execution */ + +/* + * FSP registers + * + * All of the below register definitions come from the FSP0 "Black Widow" spec + * They are the same for FSP1 except they are presented big-endian vs + * little-endian for FSP0 -- which used PCI + * all regs are 4 bytes wide, and we read the larger data areas in 4 byte + * granularity as well + * + * there are actually two defined sets of MBX registers + * MBX2 can't generate interrupts to the host and only MBX1 is currently + * used by firmware running on the FSP, so we're mostly ignoring MBX2 + */ + +/* Device Reset Control Register */ +#define FSP_DRCR_REG 0x00 +#define FSP_DRCR_CLR_REG 0x04 + +/* Bit masks for DRCR */ +#define FSP_DRCR_CMD_VALID PPC_BIT32(16) +#define FSP_DRCR_TERMINATE PPC_BIT32(17) +#define FSP_DRCR_PREP_FOR_RESET PPC_BIT32(23) +#define FSP_DRCR_CLEAR_DISR PPC_BIT32(30) + +/* DRCR commands need the CMD_VALID bit set */ +#define FSP_PREP_FOR_RESET_CMD (FSP_DRCR_CMD_VALID | \ + FSP_DRCR_PREP_FOR_RESET) +#define FSP_DRCR_ACK_MASK (0xff << 8) + +/* Device Immediate Status Register */ +#define FSP_DISR_REG 0x08 +#define FSP_DISR_CLR_REG 0x0C + +/* Bit masks for DISR */ +#define FSP_DISR_FSP_UNIT_CHECK PPC_BIT32(16) +#define FSP_DISR_FSP_RUNTIME_TERM PPC_BIT32(21) +#define FSP_DISR_FSP_RR_COMPLETE PPC_BIT32(22) +#define FSP_DISR_FSP_FLASH_TERM PPC_BIT32(23) +#define FSP_DISR_RUNTIME_STATE_SYNCD PPC_BIT32(24) +#define FSP_DISR_DBG_IN_PROGRESS PPC_BIT32(25) +#define FSP_DISR_FSP_IN_RR PPC_BIT32(26) +#define FSP_DISR_FSP_REBOOT_IN_PROGRESS PPC_BIT32(27) +#define FSP_DISR_CRIT_OP_IN_PROGRESS PPC_BIT32(28) +#define FSP_DISR_STATUS_ACK_RXD PPC_BIT32(31) + +#define FSP_DISR_HIR_TRIGGER_MASK (FSP_DISR_FSP_UNIT_CHECK | \ + FSP_DISR_FSP_RUNTIME_TERM | \ + FSP_DISR_FSP_FLASH_TERM) + +/* The host version of the control register shares bits with the FSP's + * control reg. Those bits are defined such that one side can set + * a bit and the other side can clear it + */ +#define FSP_MBX1_HCTL_REG 0x080 /* AKA DSCR1 */ +#define FSP_MBX1_FCTL_REG 0x090 +#define FSP_MBX2_HCTL_REG 0x0a0 /* AKA DSCR2 */ +#define FSP_MBX2_FCTL_REG 0x0b0 + +/* Bits in the control reg */ +#define FSP_MBX_CTL_PTS (1 << 31) +#define FSP_MBX_CTL_ABORT (1 << 30) +#define FSP_MBX_CTL_SPPEND (1 << 29) +#define FSP_MBX_CTL_HPEND (1 << 28) +#define FSP_MBX_CTL_XDN (1 << 26) +#define FSP_MBX_CTL_XUP (1 << 25) +#define FSP_MBX_CTL_HCHOST_MASK (0xf << 20) +#define FSP_MBX_CTL_HCHOST_SHIFT 20 +#define FSP_MBX_CTL_DCHOST_MASK (0xff << 12) +#define FSP_MBX_CTL_DCHOST_SHIFT 12 +#define FSP_MBX_CTL_HCSP_MASK (0xf << 8) +#define FSP_MBX_CTL_HCSP_SHIFT 8 +#define FSP_MBX_CTL_DCSP_MASK (0xff) +#define FSP_MBX_CTL_DCSP_SHIFT 0 + +/* Three header registers owned by the host */ +#define FSP_MBX1_HHDR0_REG 0x84 +#define FSP_MBX1_HHDR1_REG 0x88 +#define FSP_MBX1_HHDR2_REG 0x8C +#define FSP_MBX2_HHDR0_REG 0xa4 +#define FSP_MBX2_HHDR1_REG 0xa8 +#define FSP_MBX2_HHDR2_REG 0xaC + +/* SP Doorbell Error Status register */ +#define FSP_SDES_REG 0xc0 + +/* Host Doorbell Error Status register */ +#define FSP_HDES_REG 0xc4 + +/* Bit definitions for both SDES and HDES + * + * Notes: + * + * - CLR: is written to clear the status and always reads + * as 0. It can be used to detect an error state (a HB + * freeze will return all 1's) + * - ILLEGAL: illegal operation such as host trying to write + * to an FSP only register etc... + * - WFULL: set if host tried to write to the SP doorbell while + * the pending bit is still set + * - REMPTY: tried to read while host pending bit not set + * - PAR: SP RAM parity error + */ +#define FSP_DBERRSTAT_ILLEGAL1 (1 << 27) +#define FSP_DBERRSTAT_WFULL1 (1 << 26) +#define FSP_DBERRSTAT_REMPTY1 (1 << 25) +#define FSP_DBERRSTAT_PAR1 (1 << 24) +#define FSP_DBERRSTAT_CLR1 (1 << 16) +#define FSP_DBERRSTAT_ILLEGAL2 (1 << 11) +#define FSP_DBERRSTAT_WFULL2 (1 << 10) +#define FSP_DBERRSTAT_REMPTY2 (1 << 9) +#define FSP_DBERRSTAT_PAR2 (1 << 8) +#define FSP_DBERRSTAT_CLR2 (1 << 0) + +/* Host Doorbell Interrupt Register and mask + * + * Note that while HDIR has bits for MBX2, only + * MBX1 can actually generate interrupts. Thus only the + * MBX1 bits are implemented in the mask register. + */ +#define FSP_HDIR_REG 0xc8 +#define FSP_HDIM_SET_REG 0xcc +#define FSP_HDIM_CLR_REG 0xd0 +#define FSP_DBIRQ_ERROR2 (1 << 10) +#define FSP_DBIRQ_XUP2 (1 << 9) +#define FSP_DBIRQ_HPEND2 (1 << 8) +#define FSP_DBIRQ_ERROR1 (1 << 2) +#define FSP_DBIRQ_XUP1 (1 << 1) +#define FSP_DBIRQ_HPEND1 (1 << 0) +#define FSP_DBIRQ_MBOX1 (FSP_DBIRQ_ERROR1 | FSP_DBIRQ_XUP1 | \ + FSP_DBIRQ_HPEND1) +#define FSP_DBIRQ_MBOX2 (FSP_DBIRQ_ERROR2 | FSP_DBIRQ_XUP2 | \ + FSP_DBIRQ_HPEND2) +#define FSP_DBIRQ_ALL (FSP_DBIRQ_MBOX1 | FSP_DBIRQ_MBOX2) + +/* Doorbell Interrupt Register (FSP internal interrupt latch + * read-only on host side + */ +#define FSP_PDIR_REG 0xd4 +/* And associated mask */ +#define FSP_PDIM_SET_REG 0xd8 +#define FSP_PDIM_CLR_REG 0xdc + +/* Bits for the above */ +#define FSP_PDIRQ_ABORT2 (1 << 7) +#define FSP_PDIRQ_ABORT1 (1 << 6) +#define FSP_PDIRQ_ERROR2 (1 << 5) +#define FSP_PDIRQ_ERROR1 (1 << 4) +#define FSP_PDIRQ_XDN2 (1 << 3) +#define FSP_PDIRQ_XDN1 (1 << 2) +#define FSP_PDIRQ_SPPEND2 (1 << 1) +#define FSP_PDIRQ_SPPEND1 (1 << 0) + +/* FSP owned headers */ +#define FSP_MBX1_FHDR0_REG 0x094 +#define FSP_MBX1_FHDR1_REG 0x098 +#define FSP_MBX1_FHDR2_REG 0x09C +#define FSP_MBX2_FHDR0_REG 0x0b4 +#define FSP_MBX2_FHDR1_REG 0x0b8 +#define FSP_MBX2_FHDR2_REG 0x0bC + +/* Data areas, we can only write to host data, and read from FSP data + * + * Each area is 0x140 bytes long + */ +#define FSP_MBX1_HDATA_AREA 0x100 +#define FSP_MBX1_FDATA_AREA 0x200 +#define FSP_MBX2_HDATA_AREA 0x300 +#define FSP_MBX2_FDATA_AREA 0x400 + +/* These are scratch registers */ +#define FSP_SCRATCH0_REG 0xe0 +#define FSP_SCRATCH1_REG 0xe4 +#define FSP_SCRATCH2_REG 0xe8 +#define FSP_SCRATCH3_REG 0xec + +/* This is what the cmd_sub_mod will have for FSP_MCLASS_RR_EVENT */ +#define FSP_RESET_START 0x1 +#define FSP_RELOAD_COMPLETE 0x2 + +/* + * Message classes + */ + +/* The FSP_MCLASS_RR_EVENT is a special message class that doesn't + * participate in mbox event related activities. Its relevant only + * for hypervisor internal use. So, handle it specially for command + * class extraction too. + */ +#define FSP_MCLASS_RR_EVENT 0xaa /* see FSP_R/R defines above */ +#define FSP_MCLASS_FIRST 0xce +#define FSP_MCLASS_SERVICE 0xce +#define FSP_MCLASS_IPL 0xcf +#define FSP_MCLASS_PCTRL_MSG 0xd0 +#define FSP_MCLASS_PCTRL_ABORTS 0xd1 +#define FSP_MCLASS_ERR_LOG 0xd2 +#define FSP_MCLASS_CODE_UPDATE 0xd3 +#define FSP_MCLASS_FETCH_SPDATA 0xd4 +#define FSP_MCLASS_FETCH_HVDATA 0xd5 +#define FSP_MCLASS_NVRAM 0xd6 +#define FSP_MCLASS_MBOX_SURV 0xd7 +#define FSP_MCLASS_RTC 0xd8 +#define FSP_MCLASS_SMART_CHIP 0xd9 +#define FSP_MCLASS_INDICATOR 0xda +#define FSP_MCLASS_HMC_INTFMSG 0xe0 +#define FSP_MCLASS_HMC_VT 0xe1 +#define FSP_MCLASS_HMC_BUFFERS 0xe2 +#define FSP_MCLASS_SHARK 0xe3 +#define FSP_MCLASS_MEMORY_ERR 0xe4 +#define FSP_MCLASS_CUOD_EVENT 0xe5 +#define FSP_MCLASS_HW_MAINT 0xe6 +#define FSP_MCLASS_VIO 0xe7 +#define FSP_MCLASS_SRC_MSG 0xe8 +#define FSP_MCLASS_DATA_COPY 0xe9 +#define FSP_MCLASS_TONE 0xea +#define FSP_MCLASS_VIRTUAL_NVRAM 0xeb +#define FSP_MCLASS_TORRENT 0xec +#define FSP_MCLASS_NODE_PDOWN 0xed +#define FSP_MCLASS_DIAG 0xee +#define FSP_MCLASS_PCIE_LINK_TOPO 0xef +#define FSP_MCLASS_OCC 0xf0 +#define FSP_MCLASS_TRUSTED_BOOT 0xf1 +#define FSP_MCLASS_HBRT 0xf2 +#define FSP_MCLASS_LAST 0xf2 + +/* + * Commands are provided in rxxyyzz form where: + * + * - r is 0: no response or 1: response expected + * - xx is class + * - yy is subcommand + * - zz is mod + * + * WARNING: We only set the r bit for HV->FSP commands + * long run, we want to remove use of that bit + * and instead have a table of all commands in + * the FSP driver indicating which ones take a + * response... + */ + +/* + * Class 0xCF + */ +#define FSP_CMD_OPL 0x0cf7100 /* HV->FSP: Operational Load Compl. */ +#define FSP_CMD_HV_STATE_CHG 0x0cf0200 /* FSP->HV: Request HV state change */ +#define FSP_RSP_HV_STATE_CHG 0x0cf8200 +#define FSP_CMD_SP_NEW_ROLE 0x0cf0700 /* FSP->HV: FSP assuming a new role */ +#define FSP_RSP_SP_NEW_ROLE 0x0cf8700 +#define FSP_CMD_SP_RELOAD_COMP 0x0cf0102 /* FSP->HV: FSP reload complete */ + + +/* + * Class 0xCE + */ +#define FSP_CMD_ACK_DUMP 0x1ce0200 /* HV->FSP: Dump ack */ +#define FSP_CMD_HV_QUERY_CAPS 0x1ce0400 /* HV->FSP: Query capabilities */ +#define FSP_RSP_HV_QUERY_CAPS 0x1ce8400 +#define FSP_CMD_SP_QUERY_CAPS 0x0ce0501 /* FSP->HV */ +#define FSP_RSP_SP_QUERY_CAPS 0x0ce8500 +#define FSP_CMD_GET_IPL_SIDE 0x1ce0600 /* HV->FSP: Get IPL side and speed */ +#define FSP_CMD_SET_IPL_SIDE 0x1ce0780 /* HV->FSP: Set next IPL side */ +#define FSP_CMD_ERRLOG_PHYP_ACK 0x1ce0800 /* HV->FSP */ +#define FSP_RSP_ERRLOG_PHYP_ACK 0x0ce8800 /* FSP->HV */ +#define FSP_CMD_ERRLOG_GET_PLID 0x0ce0900 /* FSP->HV: Get PLID */ +#define FSP_RSP_ERRLOG_GET_PLID 0x0ce8900 /* HV->FSP */ +#define FSP_CMD_SA_INDICATOR 0x1ce1000 /* HV->FSP: read/update SAI */ +#define FSP_RSP_SA_INDICATOR 0x0ce9000 /* FSP->HV */ +#define FSP_CMD_QUERY_SPARM 0x1ce1200 /* HV->FSP: System parameter query */ +#define FSP_RSP_QUERY_SPARM 0x0ce9200 /* FSP->HV: System parameter resp */ +#define FSP_CMD_SET_SPARM_1 0x1ce1301 /* HV->FSP: Set system parameter */ +#define FSP_CMD_SET_SPARM_2 0x1ce1302 /* HV->FSP: Set system parameter TCE */ +#define FSP_RSP_SET_SPARM 0x0ce9300 /* FSP->HV: Set system parameter resp */ +#define FSP_CMD_SP_SPARM_UPD_0 0x0ce1600 /* FSP->HV: Sysparm updated no data */ +#define FSP_CMD_SP_SPARM_UPD_1 0x0ce1601 /* FSP->HV: Sysparm updated data */ +#define FSP_CMD_HYP_MDST_TABLE 0x1ce2600 /* HV->FSP: Sapphire MDST table */ +#define FSP_CMD_TPO_READ 0x1ce4201 /* FSP->HV */ +#define FSP_CMD_TPO_WRITE 0x1ce4301 /* HV->FSP */ +#define FSP_CMD_TPO_DISABLE 0x1ce4400 /* HV->FSP */ +#define FSP_CMD_STATUS_REQ 0x1ce4800 /* HV->FSP: Request normal panel status */ +#define FSP_CMD_STATUS_EX1_REQ 0x1ce4802 /* HV->FSP: Request extended 1 panel status */ +#define FSP_CMD_STATUS_EX2_REQ 0x1ce4803 /* HV->FSP: Request extended 2 panel status */ +#define FSP_CMD_CONTINUE_ACK 0x0ce5700 /* HV->FSP: HV acks CONTINUE IPL */ +#define FSP_CMD_HV_FUNCTNAL 0x1ce5707 /* HV->FSP: Set HV functional state */ +#define FSP_CMD_FSP_FUNCTNAL 0x0ce5708 /* FSP->HV: FSP functional state */ +#define FSP_CMD_CONTINUE_IPL 0x0ce7000 /* FSP->HV: HV has control */ +#define FSP_RSP_SYS_DUMP_OLD 0x0ce7800 /* FSP->HV: Sys Dump Available */ +#define FSP_RSP_SYS_DUMP 0x0ce7802 /* FSP->HV: Sys Dump Available */ +#define FSP_RSP_RES_DUMP 0x0ce7807 /* FSP->HV: Resource Dump Available */ +#define FSP_CMD_PCI_POWER_CONF 0x1ce1b00 /* HV->FSP: Send PCIe list to FSP */ +#define FSP_CMD_POWERDOWN_NORM 0x1ce4d00 /* HV->FSP: Normal power down */ +#define FSP_CMD_POWERDOWN_QUICK 0x1ce4d01 /* HV->FSP: Quick power down */ +#define FSP_CMD_POWERDOWN_PCIRS 0x1ce4d02 /* HV->FSP: PCI cfg reset power dwn */ +#define FSP_CMD_REBOOT 0x1ce4e00 /* HV->FSP: Standard IPL */ +#define FSP_CMD_DEEP_REBOOT 0x1ce4e04 /* HV->FSP: Deep IPL */ +#define FSP_CMD_INIT_DPO 0x0ce5b00 /* FSP->HV: Initialize Delayed Power Off */ +#define FSP_RSP_INIT_DPO 0x0cedb00 /* HV->FSP: Response for DPO init command */ +#define FSP_CMD_GET_HIR_PLID 0x0ce0900 /* FSP->HV: Get Platform Log ID with + * reason for Host Initiated Reset. + */ +#define FSP_RSP_GET_HIR_PLID 0x0ce8900 /* HV->FSP: Reply with PLID */ +#define FSP_CMD_PANELSTATUS 0x0ce5c00 /* FSP->HV */ +#define FSP_CMD_PANELSTATUS_EX1 0x0ce5c02 /* FSP->HV */ +#define FSP_CMD_PANELSTATUS_EX2 0x0ce5c03 /* FSP->HV */ + +/* SAI read/update sub commands */ +#define FSP_LED_RESET_REAL_SAI 0x00 +#define FSP_LED_READ_REAL_SAI 0x02 +#define FSP_LED_RESET_PARTITION_SAI 0x80 +#define FSP_LED_SET_PARTITION_SAI 0x81 +#define FSP_LED_READ_PARTITION_SAI 0x82 +#define FSP_LED_READ_PLAT_SAI 0x83 +#define FSP_LED_RESET_PLAT_SAI 0x84 +#define FSP_LED_SET_PLAT_SAI 0x85 + +/* + * Class 0xD2 + */ +#define FSP_CMD_CREATE_ERRLOG 0x1d21000 /* HV->FSP */ +#define FSP_RSP_CREATE_ERRLOG 0x0d29000 /* FSP->HV */ +#define FSP_CMD_ERRLOG_NOTIFICATION 0x0d25a00 /* FSP->HV */ +#define FSP_RSP_ERRLOG_NOTIFICATION 0x0d2da00 /* HV->FSP */ +#define FSP_RSP_ELOG_NOTIFICATION_ERROR 0x1d2dafe /* HV->FSP */ +#define FSP_CMD_FSP_DUMP_INIT 0x1d21200 /* HV->FSP: FSP dump init */ + +/* + * Class 0xD0 + */ +#define FSP_CMD_SPCN_PASSTHRU 0x1d05400 /* HV->FSP */ +#define FSP_RSP_SPCN_PASSTHRU 0x0d0d400 /* FSP->HV */ + +/* + * Class 0xD3 + */ +#define FSP_CMD_FLASH_START 0x01d30101 /* HV->FSP: Code update start */ +#define FSP_CMD_FLASH_COMPLETE 0x01d30201 /* HV->FSP: Code update complete */ +#define FSP_CMD_FLASH_ABORT 0x01d302ff /* HV->FSP: Code update complete */ +#define FSP_CMD_FLASH_WRITE 0x01d30300 /* HV->FSP: Write LID */ +#define FSP_CMD_FLASH_DEL 0x01d30500 /* HV->FSP: Delete LID */ +#define FSP_CMD_FLASH_NORMAL 0x01d30401 /* HV->FSP: Commit (T -> P) */ +#define FSP_CMD_FLASH_REMOVE 0x01d30402 /* HV->FSP: Reject (P -> T) */ +#define FSP_CMD_FLASH_SWAP 0x01d30403 /* HV->FSP: Swap */ +#define FSP_CMD_FLASH_OUTC 0x00d30601 /* FSP->HV: Out of band commit */ +#define FSP_CMD_FLASH_OUTR 0x00d30602 /* FSP->HV: Out of band reject */ +#define FSP_CMD_FLASH_OUTS 0x00d30603 /* FSP->HV: Out of band swap */ +#define FSP_CMD_FLASH_OUT_RSP 0x00d38600 /* HV->FSP: Out of band Resp */ +#define FSP_CMD_FLASH_CACHE 0x00d30700 /* FSP->HV: Update LID cache */ +#define FSP_CMD_FLASH_CACHE_RSP 0x00d38700 /* HV->FSP: Update LID cache Resp */ + +/* + * Class 0xD4 + */ +#define FSP_CMD_FETCH_SP_DATA 0x1d40101 /* HV->FSP: Fetch & DMA data */ +#define FSP_CMD_WRITE_SP_DATA 0x1d40201 /* HV->FSP: Fetch & DMA data */ +#define FSP_CMD_FETCH_PLAT_DATA 0x1d40500 /* HV->FSP: Platform function data */ +#define FSP_CMD_SEND_PLAT_DATA 0x0d40501 /* FSP->HV */ +#define FSP_RSP_PLAT_DATA 0x0d48500 /* HV->FSP */ + +/* Data set IDs for SP data commands */ +#define FSP_DATASET_SP_DUMP 0x01 +#define FSP_DATASET_HW_DUMP 0x02 +#define FSP_DATASET_ERRLOG 0x03 /* error log entry */ +#define FSP_DATASET_MASTER_LID 0x04 +#define FSP_DATASET_NONSP_LID 0x05 +#define FSP_DATASET_ELID_RDATA 0x06 +#define FSP_DATASET_BLADE_PARM 0x07 +#define FSP_DATASET_LOC_PORTMAP 0x08 +#define FSP_DATASET_SYSIND_CAP 0x09 +#define FSP_DATASET_FSP_RSRCDMP 0x0a +#define FSP_DATASET_HBRT_BLOB 0x0b + +/* Adjustment to get T side LIDs */ +#define ADJUST_T_SIDE_LID_NO 0x8000 + +/* + * Class 0xD5 + */ +#define FSP_CMD_ALLOC_INBOUND 0x0d50400 /* FSP->HV: Allocate inbound buf. */ +#define FSP_RSP_ALLOC_INBOUND 0x0d58400 + +/* + * Class 0xD7 + */ +#define FSP_CMD_SURV_HBEAT 0x1d70000 /* ? */ +#define FSP_CMD_SURV_ACK 0x0d78000 /* ? */ + +/* + * Class 0xD8 + */ +#define FSP_CMD_READ_TOD 0x1d82000 /* HV->FSP */ +#define FSP_CMD_READ_TOD_EXT 0x1d82001 /* HV->FSP */ +#define FSP_CMD_WRITE_TOD 0x1d82100 /* HV->FSP */ +#define FSP_CMD_WRITE_TOD_EXT 0x1d82101 /* HV->FSP */ + +/* + * Class 0xDA + */ +#define FSP_CMD_GET_LED_LIST 0x00da1101 /* Location code information structure */ +#define FSP_RSP_GET_LED_LIST 0x00da9100 +#define FSP_CMD_RET_LED_BUFFER 0x00da1102 /* Location code buffer information */ +#define FSP_RSP_RET_LED_BUFFER 0x00da9100 +#define FSP_CMD_GET_LED_STATE 0x00da1103 /* Retrieve Indicator State */ +#define FSP_RSP_GET_LED_STATE 0x00da9100 +#define FSP_CMD_SET_LED_STATE 0x00da1104 /* Set Service Indicator State */ +#define FSP_RSP_SET_LED_STATE 0x00da9100 +#define FSP_CMD_GET_MTMS_LIST 0x00da1105 /* Get MTMS and config ID list */ +#define FSP_RSP_GET_MTMS_LIST 0x00da9100 +#define FSP_CMD_SET_ENCL_MTMS 0x00da1106 /* Set MTMS */ +#define FSP_RSP_SET_ENCL_MTMS 0x00da9100 +#define FSP_CMD_SET_ENCL_CNFG 0x00da1107 /* Set config ID */ +#define FSP_RSP_SET_ENCL_CNFG 0x00da9100 +#define FSP_CMD_CLR_INCT_ENCL 0x00da1108 /* Clear inactive address */ +#define FSP_RSP_CLR_INCT_ENCL 0x00da9100 +#define FSP_CMD_RET_MTMS_BUFFER 0x00da1109 /* Return MTMS buffer */ +#define FSP_RSP_RET_MTMS_BUFFER 0x00da9100 +#define FSP_CMD_ENCL_MCODE_INIT 0x00da110A /* Mcode update (Initiate download) */ +#define FSP_RSP_ENCL_MCODE_INIT 0x00da9100 +#define FSP_CMD_ENCL_MCODE_INTR 0x00da110B /* Mcode update (Interrupt download) */ +#define FSP_RSP_ENCL_MCODE_INTR 0x00da9100 +#define FSP_CMD_ENCL_POWR_TRACE 0x00da110D /* Enclosure power network trace */ +#define FSP_RSP_ENCL_POWR_TRACE 0x00da9100 +#define FSP_CMD_RET_ENCL_TRACE_BUFFER 0x00da110E /* Return power trace buffer */ +#define FSP_RSP_RET_ENCL_TRACE_BUFFER 0x00da9100 +#define FSP_CMD_GET_SPCN_LOOP_STATUS 0x00da110F /* Get SPCN loop status */ +#define FSP_RSP_GET_SPCN_LOOP_STATUS 0x00da9100 +#define FSP_CMD_INITIATE_LAMP_TEST 0x00da1300 /* Initiate LAMP test */ + +/* + * Class 0xE0 + * + * HACK ALERT: We mark E00A01 (associate serial port) as not needing + * a response. We need to do that because the FSP will send as a result + * an Open Virtual Serial of the same class *and* expect a reply before + * it will respond to associate serial port. That breaks our logic of + * supporting only one cmd/resp outstanding per class. + */ +#define FSP_CMD_HMC_INTF_QUERY 0x0e00100 /* FSP->HV */ +#define FSP_RSP_HMC_INTF_QUERY 0x0e08100 /* HV->FSP */ +#define FSP_CMD_ASSOC_SERIAL 0x0e00a01 /* HV->FSP: Associate with a port */ +#define FSP_RSP_ASSOC_SERIAL 0x0e08a00 /* FSP->HV */ +#define FSP_CMD_UNASSOC_SERIAL 0x0e00b01 /* HV->FSP: Deassociate */ +#define FSP_RSP_UNASSOC_SERIAL 0x0e08b00 /* FSP->HV */ +#define FSP_CMD_OPEN_VSERIAL 0x0e00601 /* FSP->HV: Open serial session */ +#define FSP_RSP_OPEN_VSERIAL 0x0e08600 /* HV->FSP */ +#define FSP_CMD_CLOSE_VSERIAL 0x0e00701 /* FSP->HV: Close serial session */ +#define FSP_RSP_CLOSE_VSERIAL 0x0e08700 /* HV->FSP */ +#define FSP_CMD_CLOSE_HMC_INTF 0x0e00300 /* FSP->HV: Close HMC interface */ +#define FSP_RSP_CLOSE_HMC_INTF 0x0e08300 /* HV->FSP */ + +/* + * Class E1 + */ +#define FSP_CMD_VSERIAL_IN 0x0e10100 /* FSP->HV */ +#define FSP_CMD_VSERIAL_OUT 0x0e10200 /* HV->FSP */ + +/* + * Class E6 + */ +#define FSP_CMD_TOPO_ENABLE_DISABLE 0x0e60600 /* FSP->HV */ +#define FSP_RSP_TOPO_ENABLE_DISABLE 0x0e68600 /* HV->FSP */ + +/* + * Class E8 + */ +#define FSP_CMD_READ_SRC 0x1e84a40 /* HV->FSP */ +#define FSP_CMD_DISP_SRC_INDIR 0x1e84a41 /* HV->FSP */ +#define FSP_CMD_DISP_SRC_DIRECT 0x1e84a42 /* HV->FSP */ +#define FSP_CMD_CLEAR_SRC 0x1e84b00 /* HV->FSP */ +#define FSP_CMD_DIS_SRC_ECHO 0x1e87600 /* HV->FSP */ + +/* + * Class EB + */ +#define FSP_CMD_GET_VNVRAM_SIZE 0x01eb0100 /* HV->FSP */ +#define FSP_CMD_OPEN_VNVRAM 0x01eb0200 /* HV->FSP */ +#define FSP_CMD_READ_VNVRAM 0x01eb0300 /* HV->FSP */ +#define FSP_CMD_WRITE_VNVRAM 0x01eb0400 /* HV->FSP */ +#define FSP_CMD_GET_VNV_STATS 0x00eb0500 /* FSP->HV */ +#define FSP_RSP_GET_VNV_STATS 0x00eb8500 +#define FSP_CMD_FREE_VNV_STATS 0x00eb0600 /* FSP->HV */ +#define FSP_RSP_FREE_VNV_STATS 0x00eb8600 + +/* + * Class 0xEE + */ +#define FSP_RSP_DIAG_LINK_ERROR 0x00ee1100 /* FSP->HV */ +#define FSP_RSP_DIAG_ACK_TIMEOUT 0x00ee0000 /* FSP->HV */ + +/* + * Class F0 + */ +#define FSP_CMD_LOAD_OCC 0x00f00100 /* FSP->HV */ +#define FSP_RSP_LOAD_OCC 0x00f08100 /* HV->FSP */ +#define FSP_CMD_LOAD_OCC_STAT 0x01f00300 /* HV->FSP */ +#define FSP_CMD_RESET_OCC 0x00f00200 /* FSP->HV */ +#define FSP_RSP_RESET_OCC 0x00f08200 /* HV->FSP */ +#define FSP_CMD_RESET_OCC_STAT 0x01f00400 /* HV->FSP */ + +/* + * Class E4 + */ +#define FSP_CMD_MEM_RES_CE 0x00e40300 /* FSP->HV: Memory resilience CE */ +#define FSP_CMD_MEM_RES_UE 0x00e40301 /* FSP->HV: Memory resilience UE */ +#define FSP_CMD_MEM_RES_UE_SCRB 0x00e40302 /* FSP->HV: UE detected by scrub */ +#define FSP_RSP_MEM_RES 0x00e48300 /* HV->FSP */ +#define FSP_CMD_MEM_DYN_DEALLOC 0x00e40500 /* FSP->HV: Dynamic mem dealloc */ +#define FSP_RSP_MEM_DYN_DEALLOC 0x00e48500 /* HV->FSP */ + +/* + * Class F2 + */ +#define FSP_CMD_HBRT_TO_FSP 0x1f20100 /* HV->FSP: HBRT message */ +#define FSP_CMD_FSP_TO_HBRT 0x0f20200 /* FSP->HV: HBRT message */ +#define FSP_RSP_FSP_TO_HBRT 0x0f28200 /* HV->FSP: HBRT message */ + + +/* + * Functions exposed to the rest of skiboot + */ + +/* An FSP message */ + +enum fsp_msg_state { + fsp_msg_unused = 0, + fsp_msg_queued, + fsp_msg_sent, + fsp_msg_wresp, + fsp_msg_done, + fsp_msg_timeout, + fsp_msg_incoming, + fsp_msg_response, + fsp_msg_cancelled, +}; + +struct fsp_msg { + /* + * User fields. Don't populate word0.seq (upper 16 bits), this + * will be done by fsp_queue_msg() + */ + u8 dlen; /* not including word0/word1 */ + u32 word0; /* seq << 16 | cmd */ + u32 word1; /* mod << 8 | sub */ + union { + __be32 words[14]; + u8 bytes[56]; + } data; + + /* Completion function. Called with no lock held */ + void (*complete)(struct fsp_msg *msg); + void *user_data; + + /* + * Driver updated fields + */ + + /* Current msg state */ + enum fsp_msg_state state; + + /* Set if the message expects a response */ + bool response; + + /* Response will be filed by driver when response received */ + struct fsp_msg *resp; + + /* Internal queuing */ + struct list_node link; +}; + +static inline u32 fsp_msg_get_data_word(struct fsp_msg *msg, unsigned long i) +{ + return be32_to_cpu(msg->data.words[i]); +} + +static inline void fsp_msg_set_data_word(struct fsp_msg *msg, unsigned long i, u32 w) +{ + msg->data.words[i] = cpu_to_be32(w); +} + +/* This checks if a message is still "in progress" in the FSP driver */ +static inline bool fsp_msg_busy(struct fsp_msg *msg) +{ + switch(msg->state) { + case fsp_msg_unused: + case fsp_msg_done: + case fsp_msg_timeout: + case fsp_msg_response: /* A response is considered a completed msg */ + return false; + default: + break; + } + return true; +} + +static inline u32 fsp_msg_cmd(const struct fsp_msg *msg) +{ + u32 cmd_sub_mod; + cmd_sub_mod = (msg->word0 & 0xff) << 16; + cmd_sub_mod |= (msg->word1 & 0xff) << 8; + cmd_sub_mod |= (msg->word1 & 0xff00) >> 8; + return cmd_sub_mod; +} + +/* Initialize the FSP mailbox driver */ +extern void fsp_init(void); + +/* Perform the OPL sequence */ +extern void fsp_opl(void); + +/* Check if system has an FSP */ +extern bool fsp_present(void); + +/* Allocate and populate an fsp_msg structure + * + * WARNING: Do _NOT_ use free() on an fsp_msg, use fsp_freemsg() + * instead as we will eventually use pre-allocated message pools + */ +extern struct fsp_msg *fsp_allocmsg(bool alloc_response) __warn_unused_result; +extern struct fsp_msg *fsp_mkmsg(u32 cmd_sub_mod, u32 add_words, ...) __warn_unused_result; + +/* Populate a pre-allocated msg */ +extern void fsp_fillmsg(struct fsp_msg *msg, u32 cmd_sub_mod, u32 add_words, ...); + +/* Free a message + * + * WARNING: This will also free an attached response if any + */ +extern void fsp_freemsg(struct fsp_msg *msg); + +/* Free a message and not the attached reply */ +extern void __fsp_freemsg(struct fsp_msg *msg); + +/* Cancel a message from the msg queue + * + * WARNING: * This is intended for use only in the FSP r/r scenario. + * * This will also free an attached response if any + */ +extern void fsp_cancelmsg(struct fsp_msg *msg); + +/* Enqueue it in the appropriate FSP queue + * + * NOTE: This supports being called with the FSP lock already + * held. This is the only function in this module that does so + * and is meant to be used that way for sending serial "poke" + * commands to the FSP. + */ +extern int fsp_queue_msg(struct fsp_msg *msg, + void (*comp)(struct fsp_msg *msg)) __warn_unused_result; + +/* Send a fatal message to FSP + * + * This will *not* run pollers. + * Use only when attempting to get the word out about how we died. + */ +extern int fsp_fatal_msg(struct fsp_msg *msg); + +/* Synchronously send a command. If there's a response, the status is + * returned as a positive number. A negative result means an error + * sending the message. + * + * If autofree is set, the message and the reply (if any) are freed + * after extracting the status. If not set, you are responsible for + * freeing both the message and an eventual response + * + * NOTE: This will call fsp_queue_msg(msg, NULL), hence clearing the + * completion field of the message. No synchronous message is expected + * to utilize asynchronous completions. + */ +extern int fsp_sync_msg(struct fsp_msg *msg, bool autofree); + +/* Handle FSP interrupts */ +extern void fsp_interrupt(void); + +/* An FSP client is interested in messages for a given class */ +struct fsp_client { + /* Return true to "own" the message (you can free it) */ + bool (*message)(u32 cmd_sub_mod, struct fsp_msg *msg); + struct list_node link; +}; + +/* WARNING: Command class FSP_MCLASS_IPL is aliased to FSP_MCLASS_SERVICE, + * thus a client of one will get both types of messages. + * + * WARNING: Client register/unregister takes *NO* lock. These are expected + * to be called early at boot before CPUs are brought up and before + * fsp_poll() can race. The client callback is called with no lock held. + */ +extern void fsp_register_client(struct fsp_client *client, u8 msgclass); +extern void fsp_unregister_client(struct fsp_client *client, u8 msgclass); + +/* FSP TCE map/unmap functions */ +extern void fsp_tce_map(u32 offset, void *addr, u32 size); +extern void fsp_tce_unmap(u32 offset, u32 size); +extern void *fsp_inbound_buf_from_tce(u32 tce_token); + +/* Data fetch helper */ +extern uint32_t fsp_adjust_lid_side(uint32_t lid_no); +extern int fsp_fetch_data(uint8_t flags, uint16_t id, uint32_t sub_id, + uint32_t offset, void *buffer, size_t *length); +extern int fsp_fetch_data_queue(uint8_t flags, uint16_t id, uint32_t sub_id, + uint32_t offset, void *buffer, size_t *length, + void (*comp)(struct fsp_msg *msg)) __warn_unused_result; +extern int fsp_start_preload_resource(enum resource_id id, uint32_t idx, + void *buf, size_t *size); +extern int fsp_resource_loaded(enum resource_id id, uint32_t idx); +extern int fsp_preload_lid(uint32_t lid_no, char *buf, size_t *size); +extern int fsp_wait_lid_loaded(uint32_t lid_no); + +/* FSP console stuff */ +extern void fsp_console_preinit(void); +extern void fsp_console_init(void); +extern void fsp_console_add_nodes(void); +extern void fsp_console_select_stdout(void); +extern void fsp_console_reset(void); +extern void fsp_console_poll(void *); + +/* Mark FSP lock */ +extern void fsp_used_by_console(void); + +/* NVRAM */ +extern int fsp_nvram_info(uint32_t *total_size); +extern int fsp_nvram_start_read(void *dst, uint32_t src, uint32_t len); +extern int fsp_nvram_write(uint32_t offset, void *src, uint32_t size); + +/* RTC */ +extern void fsp_rtc_init(void); + +/* ELOG */ +extern void fsp_elog_read_init(void); +extern void fsp_elog_write_init(void); + +/* Code update */ +extern void fsp_code_update_init(void); +extern void fsp_code_update_wait_vpd(bool is_boot); + +/* Dump */ +extern void fsp_dump_init(void); +extern void fsp_fips_dump_notify(uint32_t dump_id, uint32_t dump_len); + +/* Attention Handler */ +extern void fsp_attn_init(void); + +/* MDST table */ +extern void fsp_mdst_table_init(void); + +/* This can be set by the fsp_opal_update_flash so that it can + * get called just reboot we reboot shutdown the machine. + */ +extern int (*fsp_flash_term_hook)(void); + +/* Surveillance */ +extern void fsp_init_surveillance(void); +extern void fsp_surv_query(void); + +/* IPMI */ +extern void fsp_ipmi_init(void); + +/* Reset/Reload */ +extern void fsp_reinit_fsp(void); +extern void fsp_trigger_reset(uint32_t plid); +extern void fsp_reset_links(void); +extern bool fsp_in_rr(void); + +/* FSP memory errors */ +extern void fsp_memory_err_init(void); + +/* Sensor */ +extern void fsp_init_sensor(void); +extern int64_t fsp_opal_read_sensor(uint32_t sensor_hndl, int token, + __be64 *sensor_data); + +/* Diagnostic */ +extern void fsp_init_diag(void); + +/* LED */ +extern void fsp_led_init(void); +extern void create_led_device_nodes(void); + +/* EPOW */ +extern void fsp_epow_init(void); + +/* DPO */ +extern void fsp_dpo_init(void); +extern bool fsp_dpo_pending; + +/* Chiptod */ +extern void fsp_chiptod_init(void); + +/* Terminate immediate */ +extern void __attribute__((noreturn)) ibm_fsp_terminate(const char *msg); + +void fsp_op_display(enum op_severity sev, enum op_module mod, uint16_t code); + +#endif /* __FSP_H */ diff --git a/roms/skiboot/include/hiomap.h b/roms/skiboot/include/hiomap.h new file mode 100644 index 000000000..bf09aea71 --- /dev/null +++ b/roms/skiboot/include/hiomap.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2018 IBM Corp. */ + +#ifndef __HIOMAP_H +#define __HIOMAP_H + +#include <ccan/endian/endian.h> +#include <ccan/short_types/short_types.h> +#include <compiler.h> +#include <stdint.h> + +#define HIOMAP_V1 1 +#define HIOMAP_V2 2 + +#define HIOMAP_C_RESET 1 +#define HIOMAP_C_GET_INFO 2 +#define HIOMAP_C_GET_FLASH_INFO 3 +#define HIOMAP_C_CREATE_READ_WINDOW 4 +#define HIOMAP_C_CLOSE_WINDOW 5 +#define HIOMAP_C_CREATE_WRITE_WINDOW 6 +#define HIOMAP_C_MARK_DIRTY 7 +#define HIOMAP_C_FLUSH 8 +#define HIOMAP_C_ACK 9 +#define HIOMAP_C_ERASE 10 +#define HIOMAP_C_DEVICE_NAME 11 +#define HIOMAP_C_LOCK 12 + +#define HIOMAP_E_ACK_MASK 0x3 +#define HIOMAP_E_PROTOCOL_RESET (1 << 0) +#define HIOMAP_E_WINDOW_RESET (1 << 1) +#define HIOMAP_E_FLASH_LOST (1 << 6) +#define HIOMAP_E_DAEMON_READY (1 << 7) + +struct hiomap_v2_range { + le16 offset; + le16 size; +} __packed; + +struct hiomap_v2_info { + uint8_t block_size_shift; + le16 timeout; +} __packed; + +struct hiomap_v2_flash_info { + le16 total_size; + le16 erase_granule; +} __packed; + +struct hiomap_v2_create_window { + le16 lpc_addr; + le16 size; + le16 offset; +} __packed; + +#endif /* __HIOMAP_H */ diff --git a/roms/skiboot/include/hostservices.h b/roms/skiboot/include/hostservices.h new file mode 100644 index 000000000..279591b5e --- /dev/null +++ b/roms/skiboot/include/hostservices.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __HOSTSERVICES_H +#define __HOSTSERVICES_H + +bool hservices_init(void); +void hservices_lid_preload(void); +bool hservices_lid_preload_complete(void); + +int host_services_occ_load(void); +int host_services_occ_start(void); +int host_services_occ_stop(void); + +/* No LID can be larger than 16M, but OCC lid is less than 1 MB */ + +#define HBRT_LOAD_LID_SIZE 0x100000 /* 1MB */ + +/* TODO: Detect OCC lid size at runtime */ + +/* Homer and OCC area size */ +#define HOMER_IMAGE_SIZE 0x400000 /* 4MB per-chip */ +#define OCC_COMMON_SIZE 0x800000 /* 8MB */ + +int hservice_send_error_log(uint32_t plid, uint32_t dsize, void *data); +int hservice_wakeup(uint32_t i_core, uint32_t i_mode); +int fsp_occ_reset_status(u64 chipid, s64 status); +int fsp_occ_load_start_status(u64 chipid, s64 status); +int hservice_send_hbrt_msg(void *data, u64 dsize); +void hservice_hbrt_msg_response(uint32_t rc); +void hservice_fsp_init(void); + +#endif /* __HOSTSERVICES_H */ diff --git a/roms/skiboot/include/i2c.h b/roms/skiboot/include/i2c.h new file mode 100644 index 000000000..a644bd427 --- /dev/null +++ b/roms/skiboot/include/i2c.h @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __I2C_H +#define __I2C_H + +struct i2c_request; + +struct i2c_bus { + struct list_node link; + struct dt_node *dt_node; + uint32_t opal_id; + int (*queue_req)(struct i2c_request *req); + uint64_t (*run_req)(struct i2c_request *req); + int (*check_quirk)(void *data, struct i2c_request *req, int *rc); + void *check_quirk_data; +}; + +/* + * I2C specific OPAL error codes: + * + * OPAL_I2C_TIMEOUT I2C request timed out + * OPAL_I2C_INVALID_CMD New command given when old not completed yet + * OPAL_I2C_LBUS_PARITY Local bus parity error + * OPAL_I2C_BKEND_OVERRUN Writing/reading into full/empty fifo respectively + * OPAL_I2C_BKEND_ACCESS Writing/reading more data than requested + * OPAL_I2C_ARBT_LOST I2C bus is held by some other master + * OPAL_I2C_NACK_RCVD Slave is not responding back with the ACK + * OPAL_I2C_STOP_ERR Did not able to send the STOP condtion on bus + */ + +struct i2c_request { + struct list_node link; + struct i2c_bus *bus; + enum i2c_operation { + I2C_READ, /* RAW read from the device without offset */ + I2C_WRITE, /* RAW write to the device without offset */ + SMBUS_READ, /* SMBUS protocol read from the device */ + SMBUS_WRITE, /* SMBUS protocol write to the device */ + } op; + int result; /* OPAL i2c error code */ + uint32_t dev_addr; /* Slave device address */ + uint32_t offset_bytes; /* Internal device offset */ + uint32_t offset; /* Internal device offset */ + uint32_t rw_len; /* Length of the data request */ + void *rw_buf; /* Data request buffer */ + enum i2c_request_state { + i2c_req_new, /* un-initialised */ + i2c_req_queued, /* waiting in the queue */ + i2c_req_done, /* request has been completed */ + } req_state; + + void (*completion)( /* Completion callback */ + int rc, struct i2c_request *req); + void *user_data; /* Client data */ + int retries; + uint64_t timeout; /* in ms */ +}; + +/* Generic i2c */ +extern void i2c_add_bus(struct i2c_bus *bus); +extern struct i2c_bus *i2c_find_bus_by_id(uint32_t opal_id); + +/* not generic, but useful */ +struct i2c_bus *p8_i2c_find_bus_by_port(uint32_t chip_id, int eng, int port_id); +struct dt_node *p8_i2c_add_master_node(struct dt_node *xscom, int eng_id); +struct dt_node *__p8_i2c_add_port_node(struct dt_node *master, int port_id, + uint32_t bus_speed); +struct dt_node *p8_i2c_add_port_node(struct dt_node *xscom, int eng_id, + int port_id, uint32_t bus_freq); + +struct i2c_bus *p8_i2c_add_bus(uint32_t chip_id, int eng_id, int port_id, + uint32_t bus_speed); + +int64_t i2c_queue_req(struct i2c_request *req); + +static inline uint64_t i2c_run_req(struct i2c_request *req) +{ + if (req->bus->run_req) + return req->bus->run_req(req); + return 0; +} + +static inline int i2c_check_quirk(struct i2c_request *req, int *rc) +{ + if (req->bus->check_quirk) + return req->bus->check_quirk(req->bus->check_quirk_data, req, rc); + return 0; +} + +/* I2C synchronous request API */ +int64_t i2c_request_sync(struct i2c_request *req); +int64_t i2c_request_send(int bus_id, int dev_addr, int read_write, + uint32_t offset, uint32_t offset_bytes, void* buf, + size_t buflen, int timeout); + +/* P8 implementation details */ +extern void p8_i2c_init(void); +extern void p8_i2c_interrupt(uint32_t chip_id); + +/* P9 I2C Ownership Change OCC interrupt handler */ +extern void p9_i2c_bus_owner_change(u32 chip_id); + +#endif /* __I2C_H */ diff --git a/roms/skiboot/include/imc.h b/roms/skiboot/include/imc.h new file mode 100644 index 000000000..96f9ec4b6 --- /dev/null +++ b/roms/skiboot/include/imc.h @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2016-2019 IBM Corp. */ +/* + * In-Memory Collection (IMC) Counters : + * Power9 has IMC instrumentation support with which several + * metrics of the platform can be monitored. These metrics + * are backed by the Performance Monitoring Units (PMUs) and + * their counters. IMC counters can be configured to run + * continuously from startup to shutdown and data from these + * counters are fed directly into a pre-defined memory location. + * + * Depending on the counters' location and monitoring engines, + * they are classified into three domains : + * Nest IMC, core IMC and thread IMC. + * + * Nest Counters : + * Nest counters are per-chip counters and can help in providing utilisation + * metrics like memory bandwidth, Xlink/Alink bandwidth etc. + * A microcode in OCC programs the nest counters and moves counter values to + * per chip HOMER region in a fixed offset for each unit. Engine has a + * control block structure for communication with Hypervisor(Host OS). + */ + +#ifndef __IMC_H +#define __IMC_H + +/* + * Control Block structure offset in HOMER nest Region + */ +#define P9_CB_STRUCT_OFFSET 0x1BFC00 +#define P9_CB_STRUCT_CMD 0x1BFC08 +#define P9_CB_STRUCT_SPEED 0x1BFC10 + +/* Nest microcode Status */ +#define NEST_IMC_PAUSE 0x2 +#define NEST_IMC_RUNNING 0x1 +#define NEST_IMC_NOP 0 + +/* + * Control Block Structure: + * + * Name Producer Consumer Values Desc + * IMCRunStatus IMC Code Hypervisor 0 Initializing + * (Host OS) 1 Running + * 2 Paused + * + * IMCCommand Hypervisor IMC Code 0 NOP + * 1 Resume + * 2 Pause + * 3 Clear and Restart + * + * IMCCollection Hypervisor IMC Code 0 128us + * Speed 1 256us + * 2 1ms + * 3 4ms + * 4 16ms + * 5 64ms + * 6 256ms + * 7 1000ms + * + * IMCAvailability IMC Code Hypervisor - 64-bit value describes + * the Vector Nest PMU + * availability. + * Bits 0-47 denote the + * availability of 48 different + * nest units. + * Rest are reserved. For details + * regarding which bit belongs + * to which unit, see + * include/nest_imc.h. + * If a bit is unset (0), + * then, the corresponding unit + * is unavailable. If its set (1), + * then, the unit is available. + * + * IMCRun Mode Hypervisor IMC Code 0 Normal Mode (Monitor Mode) + * 1 Debug Mode 1 (PB) + * 2 Debug Mode 2 (MEM) + * 3 Debug Mode 3 (PCIE) + * 4 Debug Mode 4 (CAPP) + * 5 Debug Mode 5 (NPU 1) + * 6 Debug Mode 6 (NPU 2) + */ +struct imc_chip_cb +{ + be64 imc_chip_run_status; + be64 imc_chip_command; + be64 imc_chip_collection_speed; + be64 imc_chip_avl_vector; + be64 imc_chip_run_mode; +} __packed; + +/* Size of IMC dtb LID (256KBytes) */ +#define MAX_DECOMPRESSED_IMC_DTB_SIZE 0x40000 +#define MAX_COMPRESSED_IMC_DTB_SIZE 0x40000 + +/* IMC device types */ +#define IMC_COUNTER_CHIP 0x10 +#define IMC_COUNTER_CORE 0x4 +#define IMC_COUNTER_THREAD 0x1 +#define IMC_COUNTER_TRACE 0x2 + +/* + * Nest IMC operations + */ +#define NEST_IMC_ENABLE 0x1 +#define NEST_IMC_DISABLE 0x2 + +/* + * Core IMC SCOMs + */ +#define CORE_IMC_EVENT_MASK_ADDR_P9 0x20010AA8ull +#define CORE_IMC_EVENT_MASK_ADDR_P10 0x20020400ull +#define CORE_IMC_EVENT_MASK 0x0402010000000000ull +#define CORE_IMC_PDBAR_MASK 0x0003ffffffffe000ull +#define CORE_IMC_HTM_MODE_ENABLE 0xE800000000000000ull +#define CORE_IMC_HTM_MODE_DISABLE 0xE000000000000000ull + +/* + * Trace IMC SCOMs for IMC trace-mode. + * + * TRACE_IMC_SCOM layout + * + * 0 4 8 12 16 20 24 28 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * [ ] [ CPMC_LOAD [2:33] + * | + * *SAMPSEL + * + * 32 36 40 44 48 52 56 60 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * ] [ ] [ ] [ ] [ RESERVED [51:63] ] + * | | | + * *CPMC1SEL *CPMC2SEL *BUFFERSIZE + */ +#define TRACE_IMC_ADDR_P9 0x20010AA9ull +#define TRACE_IMC_ADDR_P10 0x20020401ull +#define TRACE_IMC_SAMPLESEL(x) ((uint64_t)x << 62) +#define TRACE_IMC_CPMC_LOAD(x) ((0xffffffff - (uint64_t)x) << 30) +#define TRACE_IMC_CPMC1SEL(x) ((uint64_t)x << 23) +#define TRACE_IMC_CPMC2SEL(x) ((uint64_t)x << 16) +#define TRACE_IMC_BUFFERSIZE(x) ((uint64_t)x << 13) +#define TRACE_IMC_SCOM(a, b, c, d, e) (TRACE_IMC_SAMPLESEL(a) |\ + TRACE_IMC_CPMC_LOAD(b) |\ + TRACE_IMC_CPMC1SEL(c) |\ + TRACE_IMC_CPMC2SEL(d) |\ + TRACE_IMC_BUFFERSIZE(e)) + +void imc_init(void); +void imc_catalog_preload(void); +void imc_decompress_catalog(void); + +#define MAX_NEST_COMBINED_UNITS 4 +struct combined_units_node { + const char *name; + u64 unit1; + u64 unit2; +}; +#endif /* __IMC_H */ diff --git a/roms/skiboot/include/interrupts.h b/roms/skiboot/include/interrupts.h new file mode 100644 index 000000000..7ffcc6c4f --- /dev/null +++ b/roms/skiboot/include/interrupts.h @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __INTERRUPTS_H +#define __INTERRUPTS_H + +#include <stdint.h> +#include <ccan/list/list.h> + +/* Note about interrupt numbers on P8 + * ================================== + * + * On P8 the interrupts numbers are just a flat space of 19-bit, + * there is no BUID or similar. + * + * However, various unit tend to require blocks of interrupt that + * are naturally power-of-two aligned + * + * Our P8 Interrupt map consits thus of dividing the chip space + * into "blocks" of 2048 interrupts. Block 0 is for random chip + * interrupt sources (NX, PSI, OCC, ...) and keeps sources 0..15 + * clear to avoid conflits with IPIs etc.... Block 1..n are assigned + * to PHB 0..n respectively. The number of blocks is determined by the + * number of bits assigned to chips. + * + * That gives us an interrupt number made of: + * 18 n+1 n 11 10 0 + * | | | | | | + * +--------------------+------+-----------------------------+ + * | Chip# | PHB# | IVE# | + * +--------------------+------+-----------------------------+ + * + * Where n = 18 - p8_chip_id_bits + * + * For P8 we have 6 bits for Chip# as defined by p8_chip_id_bits. We + * therefore support a max of 2^6 = 64 chips. + * + * For P8NVL we have an extra PHB and so we assign 5 bits for Chip# + * and therefore support a max of 32 chips. + * + * Each PHB supports 2K interrupt sources, which is shared by + * LSI and MSI. With default configuration, MSI would use range + * [0, 0x7f7] and LSI would use [0x7f8, 0x7ff]. The interrupt + * source should be combined with IRSN to form final hardware + * IRQ. + * + */ + +uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block); +uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb); +uint32_t p8_irq_to_chip(uint32_t irq); +uint32_t p8_irq_to_block(uint32_t irq); +uint32_t p8_irq_to_phb(uint32_t irq); + +/* Total number of bits in the P8 interrupt space */ +#define P8_IRQ_BITS 19 + +/* Number of bits per block */ +#define P8_IVE_BITS 11 + +#define P8_IRQ_BLOCK_MISC 0 +#define P8_IRQ_BLOCK_PHB_BASE 1 + +/* Assignment of the "MISC" block: + * ------------------------------- + * + * PSI interface has 6 interrupt sources: + * + * FSP, OCC, FSI, LPC, Local error, Host error + * + * and thus needs a block of 8 + */ +#define P8_IRQ_MISC_PSI_BASE 0x10 /* 0x10..0x17 */ + +/* These are handled by skiboot */ +#define P8_IRQ_PSI_FSP 0 +#define P8_IRQ_PSI_OCC 1 +#define P8_IRQ_PSI_FSI 2 +#define P8_IRQ_PSI_LPC 3 +#define P8_IRQ_PSI_LOCAL_ERR 4 +#define P8_IRQ_PSI_EXTERNAL 5 /* Used for UART */ +#define P8_IRQ_PSI_IRQ_COUNT 6 + +/* TBD: NX, AS, ... + */ + +/* Note about interrupt numbers on P9 + * ================================== + * + * P9 uses a completely different interrupt controller, XIVE. + * + * It targets objects using a combination of block number and + * index within a block. However, we try to avoid exposing that + * split to the OS in order to keep some abstraction in case the + * way we allocate these change. + * + * The lowest level entity in Xive is the ESB (state bits). + * + * Those are spread between PHBs, PSI bridge and XIVE itself which + * provide a large amount of state bits for IPIs and other SW and HW + * generated interrupts by sources that don't have their own ESB logic + * + * Due to that spread, they aren't a good representation of a global + * interrupt number. + * + * Each such source however needs to be targetted at an EAS (IVT) + * entry in a table which will control targetting information and + * associate that interrupt with a logical number. + * + * Thus that table entry number represents a good "global interrupt + * number". Additionally, for the host OS, we will keep the logical + * number equal to the global number. + * + * The details of how these are assigned on P9 can be found in + * hw/xive.c. P9 HW will only use a subset of the definitions and + * functions in this file (or the corresponding core/interrupts.c). + */ + +struct irq_source; + +/* + * IRQ sources register themselves here. + * + * The "attributes" callback provides various attributes specific to + * a given interrupt, such as whether it's targetted at OPAL or the + * OS, or whether it's frequent or infrequent. The latter will be used + * later to optimize the lookup of the sources array by providing a small + * cache of the frequent interrupts. + * + * The "eoi" callback is used for XIVE interrupts in XICS emulation + * though we might expose it at some point in XIVE native mode for + * interrupts that require special EOI operations such as possibly + * the LPC interrupts on P9 that need a latch cleared in the LPCHC. + * + * The "name" callback returns a name for the interrupt in a new + * malloc()'ed block. The caller will free() it. NULL is acceptable. + */ +struct irq_source_ops { + int64_t (*set_xive)(struct irq_source *is, uint32_t isn, + uint16_t server, uint8_t priority); + int64_t (*get_xive)(struct irq_source *is, uint32_t isn, + uint16_t *server, uint8_t *priority); + uint64_t (*attributes)(struct irq_source *is, uint32_t isn); +/* LSB is the target */ +#define IRQ_ATTR_TARGET_OPAL 0x0 +#define IRQ_ATTR_TARGET_LINUX 0x1 +/* For OPAL interrupts, estimate frequency */ +#define IRQ_ATTR_TARGET_RARE 0x0 +#define IRQ_ATTR_TARGET_FREQUENT 0x2 +/* For OPAL interrupts, level vs. edge setting */ +#define IRQ_ATTR_TYPE_LSI 0x0 +#define IRQ_ATTR_TYPE_MSI 0x4 + void (*interrupt)(struct irq_source *is, uint32_t isn); + void (*eoi)(struct irq_source *is, uint32_t isn); + char *(*name)(struct irq_source *is, uint32_t isn); +}; + +struct irq_source { + uint32_t start; + uint32_t end; + const struct irq_source_ops *ops; + void *data; + struct list_node link; +}; + +extern void __register_irq_source(struct irq_source *is, bool secondary); +extern void register_irq_source(const struct irq_source_ops *ops, void *data, + uint32_t start, uint32_t count); +extern void unregister_irq_source(uint32_t start, uint32_t count); +extern struct irq_source *irq_find_source(uint32_t isn); + +/* Warning: callback is called with internal source lock held + * so don't call back into any of our irq_ APIs from it + */ +extern void irq_for_each_source(void (*cb)(struct irq_source *, void *), + void *data); + +extern uint32_t get_psi_interrupt(uint32_t chip_id); + +extern struct dt_node *add_ics_node(void); +extern void add_opal_interrupts(void); +extern uint32_t get_ics_phandle(void); + +struct cpu_thread; + +extern void reset_cpu_icp(void); +extern void icp_send_eoi(uint32_t interrupt); +extern void icp_prep_for_pm(void); +extern void icp_kick_cpu(struct cpu_thread *cpu); + +extern void init_interrupts(void); + +extern bool irq_source_eoi(uint32_t isn); +extern bool __irq_source_eoi(struct irq_source *is, uint32_t isn); + + +#endif /* __INTERRUPTS_H */ diff --git a/roms/skiboot/include/inttypes.h b/roms/skiboot/include/inttypes.h new file mode 100644 index 000000000..984c1f611 --- /dev/null +++ b/roms/skiboot/include/inttypes.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* This file exists because a bunch of files are built as part of + * unit tests as well as skiboot and inttypes.h is part of libc rather + * than gcc, so to get the magic to work when we don't have libc sitting + * around, we get to rewrite inttypes.h. + * + * Copyright 2015 IBM Corp. + */ + +#ifndef __SKIBOOT_INTTYPES_H +#define __SKIBOOT_INTTYPES_H + +#include <stdint.h> + +#ifndef __WORDSIZE +/* If we don't have __WORDSIZE it means we're *certainly* building skiboot + * which will *ALWAYS* have a word size of 32bits. + * (unless someone goes and ports skiboot to something that isn't powerpc) + */ +#define __WORDSIZE 32 +#endif + +#if __WORDSIZE == 64 +#define PRIu64 "lu" +#define PRIx64 "lx" +#else +#define PRIu64 "llu" +#define PRIx64 "llx" +#endif + +#endif diff --git a/roms/skiboot/include/io.h b/roms/skiboot/include/io.h new file mode 100644 index 000000000..f00021dcd --- /dev/null +++ b/roms/skiboot/include/io.h @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2017 IBM Corp. */ + +#ifndef __IO_H +#define __IO_H + +#ifndef __ASSEMBLY__ + +#include <compiler.h> +#include <stdint.h> +#include <processor.h> +#include <types.h> +#include <ccan/endian/endian.h> + +/* + * IO access functions + * + * __in_beXX() / __out_beXX() : non-byteswap, no barrier + * in_beXX() / out_beXX() : non-byteswap, barrier + * in_leXX() / out_leXX() : byteswap, barrier + */ + +static inline uint8_t __in_8(const volatile uint8_t *addr) +{ + uint8_t val; + asm volatile("lbzcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return val; +} + +static inline uint8_t in_8(const volatile uint8_t *addr) +{ + sync(); + return __in_8(addr); +} + +static inline uint16_t __in_be16(const volatile beint16_t *addr) +{ + __be16 val; + asm volatile("lhzcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return be16_to_cpu(val); +} + +static inline uint16_t in_be16(const volatile beint16_t *addr) +{ + sync(); + return __in_be16(addr); +} + +static inline uint16_t __in_le16(const volatile leint16_t *addr) +{ + __le16 val; + asm volatile("lhzcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return le16_to_cpu(val); +} + +static inline uint16_t in_le16(const volatile leint16_t *addr) +{ + sync(); + return __in_le16(addr); +} + +static inline uint32_t __in_be32(const volatile beint32_t *addr) +{ + __be32 val; + asm volatile("lwzcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return be32_to_cpu(val); +} + +static inline uint32_t in_be32(const volatile beint32_t *addr) +{ + sync(); + return __in_be32(addr); +} + +static inline uint32_t __in_le32(const volatile leint32_t *addr) +{ + __le32 val; + asm volatile("lwzcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return le32_to_cpu(val); +} + +static inline uint32_t in_le32(const volatile leint32_t *addr) +{ + sync(); + return __in_le32(addr); +} + +static inline uint64_t __in_be64(const volatile beint64_t *addr) +{ + __be64 val; + asm volatile("ldcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return be64_to_cpu(val); +} + +static inline uint64_t in_be64(const volatile beint64_t *addr) +{ + sync(); + return __in_be64(addr); +} + +static inline uint64_t __in_le64(const volatile leint64_t *addr) +{ + __le64 val; + asm volatile("ldcix %0,0,%1" : + "=r"(val) : "r"(addr), "m"(*addr) : "memory"); + return le64_to_cpu(val); +} + +static inline uint64_t in_le64(const volatile leint64_t *addr) +{ + sync(); + return __in_le64(addr); +} + +static inline void __out_8(volatile uint8_t *addr, uint8_t val) +{ + asm volatile("stbcix %0,0,%1" + : : "r"(val), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_8(volatile uint8_t *addr, uint8_t val) +{ + sync(); + return __out_8(addr, val); +} + +static inline void __out_be16(volatile beint16_t *addr, uint16_t val) +{ + asm volatile("sthcix %0,0,%1" + : : "r"(cpu_to_be16(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_be16(volatile beint16_t *addr, uint16_t val) +{ + sync(); + return __out_be16(addr, val); +} + +static inline void __out_le16(volatile leint16_t *addr, uint16_t val) +{ + asm volatile("sthcix %0,0,%1" + : : "r"(cpu_to_le16(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_le16(volatile leint16_t *addr, uint16_t val) +{ + sync(); + return __out_le16(addr, val); +} + +static inline void __out_be32(volatile beint32_t *addr, uint32_t val) +{ + asm volatile("stwcix %0,0,%1" + : : "r"(cpu_to_be32(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_be32(volatile beint32_t *addr, uint32_t val) +{ + sync(); + return __out_be32(addr, val); +} + +static inline void __out_le32(volatile leint32_t *addr, uint32_t val) +{ + asm volatile("stwcix %0,0,%1" + : : "r"(cpu_to_le32(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_le32(volatile leint32_t *addr, uint32_t val) +{ + sync(); + return __out_le32(addr, val); +} + +static inline void __out_be64(volatile beint64_t *addr, uint64_t val) +{ + asm volatile("stdcix %0,0,%1" + : : "r"(cpu_to_be64(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_be64(volatile beint64_t *addr, uint64_t val) +{ + sync(); + return __out_be64(addr, val); +} + +static inline void __out_le64(volatile leint64_t *addr, uint64_t val) +{ + asm volatile("stdcix %0,0,%1" + : : "r"(cpu_to_le64(val)), "r"(addr), "m"(*addr) : "memory"); +} + +static inline void out_le64(volatile leint64_t *addr, uint64_t val) +{ + sync(); + return __out_le64(addr, val); +} + +/* Assistant to macros used to access PCI config space */ +#define in_le8 in_8 +#define out_le8 out_8 + +/* Ensure completion of a load (ie, value returned to CPU) + * before continuing execution + */ +static inline void load_wait(uint64_t data) +{ + asm volatile("twi 0,%0,0;isync" : : "r" (data) : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __IO_H */ diff --git a/roms/skiboot/include/ipmi.h b/roms/skiboot/include/ipmi.h new file mode 100644 index 000000000..3e629ba40 --- /dev/null +++ b/roms/skiboot/include/ipmi.h @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __IPMI_H +#define __IPMI_H + +#include <stdint.h> +#include <ccan/list/list.h> +#include <stdbool.h> +#include <types.h> + +#define MAX_IPMI_SENSORS 255 + +/* + * IPMI codes as defined by the standard. + */ +#define IPMI_GET_DEVICE_ID_CMD 0x01 +#define IPMI_COLD_RESET_CMD 0x02 +#define IPMI_WARM_RESET_CMD 0x03 +#define IPMI_CLEAR_MSG_FLAGS_CMD 0x30 +#define IPMI_GET_DEVICE_GUID_CMD 0x08 +#define IPMI_GET_MSG_FLAGS_CMD 0x31 +#define IPMI_SEND_MSG_CMD 0x34 +#define IPMI_GET_MSG_CMD 0x33 +#define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e +#define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f +#define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35 +#define IPMI_GET_CHANNEL_INFO_CMD 0x42 + +/* + * 28. Chassis Commands + */ +#define IPMI_CHASSIS_GET_CAP_CMD 0x00 +#define IPMI_CHASSIS_GET_STATUS_CMD 0x01 +#define IPMI_CHASSIS_CONTROL_CMD 0x02 +#define IPMI_CHASSIS_RESET_CMD 0x03 +#define IPMI_CHASSIS_IDENTIFY_CMD 0x04 +#define IPMI_CHASSIS_SET_PANEL_BUTTON_EN_CMD 0x0a +#define IPMI_CHASSIS_SET_CAP_CMD 0x05 +#define IPMI_CHASSIS_SET_PWR_RESTORE_CMD 0x06 +#define IPMI_CHASSIS_SET_PWR_CYCLE_CMD 0x0b +#define IPMI_CHASSIS_GET_SYS_RESTART_CAUSE_CMD 0x07 +#define IPMI_CHASSIS_SET_SYS_BOOT_OPT_CMD 0x08 +#define IPMI_CHASSIS_GET_SYS_BOOT_OPT_CMD 0x09 +#define IPMI_CHASSIS_GET_POH_COUNTER_CMD 0x0f + + +/* 28.3. Chassis Control Command */ +#define IPMI_CHASSIS_PWR_DOWN 0x00 +#define IPMI_CHASSIS_PWR_UP 0x01 +#define IPMI_CHASSIS_PWR_CYCLE 0x02 +#define IPMI_CHASSIS_HARD_RESET 0x03 +#define IPMI_CHASSIS_PULSE_DIAG 0x04 +#define IPMI_CHASSIS_SOFT_SHUTDOWN 0x05 + +/* 20.7. ACPI Power State Command */ +#define IPMI_PWR_SYS_S0_WORKING 0x00 +#define IPMI_PWR_SYS_S1 0x01 +#define IPMI_PWR_SYS_S2 0x02 +#define IPMI_PWR_SYS_S3_SUSPEND_TO_RAM 0x03 +#define IPMI_PWR_SYS_S4_SUSPEND_TO_DISK 0x04 +#define IPMI_PWR_SYS_S5_SOFT_OFF 0x05 +#define IPMI_PWR_SYS_SUSPEND 0x06 +#define IPMI_PWR_SYS_LEGACY_ON 0x20 +#define IPMI_PWR_SYS_LEGACY_OFF 0x21 +#define IPMI_PWR_SYS_UNKNOWN 0x2a +#define IPMI_PWR_NOCHANGE 0x7f + +/* 22.{3,4} Clear / Get message flags */ +#define IPMI_MESSAGE_FLAGS_RX_MESSAGE_QUEUE (1<<0) +#define IPMI_MESSAGE_FLAGS_EVENT_BUFFER (1<<1) +#define IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT (1<<3) +#define IPMI_MESSAGE_FLAGS_OEM0 (1<<5) +#define IPMI_MESSAGE_FLAGS_OEM1 (1<<6) +#define IPMI_MESSAGE_FLAGS_OEM2 (1<<7) + +/* Firmware Progress Sensor states */ +#define IPMI_FW_PCI_INIT 0x07 +#define IPMI_FW_OS_BOOT 0x13 +#define IPMI_FW_MOTHERBOARD_INIT 0x14 + +#define IPMI_CODE(netfn, cmd) ((netfn) << 8 | (cmd)) +#define IPMI_CMD(code) ((code) & 0xff) +#define IPMI_NETFN(code) ((code) >> 8 & 0xff) + +#define IPMI_NETFN_RETURN_CODE(netfn) ((netfn) | 0x4) + +#define IPMI_NETFN_CHASSIS 0x00 +#define IPMI_NETFN_SE 0x04 +#define IPMI_NETFN_STORAGE 0x0a +#define IPMI_NETFN_APP 0x06 + +#define IPMI_WRITE_FRU IPMI_CODE(IPMI_NETFN_STORAGE, 0x12) +#define IPMI_GET_SEL_INFO IPMI_CODE(IPMI_NETFN_STORAGE, 0x40) +#define IPMI_RESERVE_SEL IPMI_CODE(IPMI_NETFN_STORAGE, 0x42) +#define IPMI_ADD_SEL_EVENT IPMI_CODE(IPMI_NETFN_STORAGE, 0x44) +#define IPMI_GET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x48) +#define IPMI_SET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x49) +#define IPMI_CHASSIS_CONTROL IPMI_CODE(IPMI_NETFN_CHASSIS, 0x02) +#define IPMI_CHASSIS_GET_BOOT_OPT IPMI_CODE(IPMI_NETFN_CHASSIS, 0x09) +#define IPMI_BMC_GET_DEVICE_ID IPMI_CODE(IPMI_NETFN_APP, 0x01) +#define IPMI_SET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x06) +#define IPMI_GET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x07) +#define IPMI_RESET_WDT IPMI_CODE(IPMI_NETFN_APP, 0x22) +#define IPMI_SET_WDT IPMI_CODE(IPMI_NETFN_APP, 0x24) +#define IPMI_SET_ENABLES IPMI_CODE(IPMI_NETFN_APP, 0x2E) +#define IPMI_GET_ENABLES IPMI_CODE(IPMI_NETFN_APP, 0x2F) +#define IPMI_CLEAR_MESSAGE_FLAGS IPMI_CODE(IPMI_NETFN_APP, 0x30) +#define IPMI_GET_MESSAGE_FLAGS IPMI_CODE(IPMI_NETFN_APP, 0x31) +#define IPMI_GET_MESSAGE IPMI_CODE(IPMI_NETFN_APP, 0x33) +#define IPMI_READ_EVENT IPMI_CODE(IPMI_NETFN_APP, 0x35) +#define IPMI_GET_BT_CAPS IPMI_CODE(IPMI_NETFN_APP, 0x36) +#define IPMI_SET_SENSOR_READING IPMI_CODE(IPMI_NETFN_SE, 0x30) + +/* + * IPMI response codes. + */ +#define IPMI_CC_NO_ERROR 0x00 +#define IPMI_NODE_BUSY_ERR 0xc0 +#define IPMI_INVALID_COMMAND_ERR 0xc1 +#define IPMI_TIMEOUT_ERR 0xc3 +#define IPMI_ERR_MSG_TRUNCATED 0xc6 +#define IPMI_REQ_LEN_INVALID_ERR 0xc7 +#define IPMI_REQ_LEN_EXCEEDED_ERR 0xc8 +#define IPMI_NOT_IN_MY_STATE_ERR 0xd5 /* IPMI 2.0 */ +#define IPMI_LOST_ARBITRATION_ERR 0x81 +#define IPMI_BUS_ERR 0x82 +#define IPMI_NAK_ON_WRITE_ERR 0x83 +#define IPMI_ERR_UNSPECIFIED 0xff + +#define IPMI_DEFAULT_INTERFACE 0 + +#define IPMI_MAX_REQ_SIZE 60 +#define IPMI_MAX_RESP_SIZE 60 + +/* + * As far as I can tell the size of PEL record is unbounded (due to + * the possible presence of the user defined section). We chose this + * size because it's what hostboot also uses and most of the OPAL logs + * are few hundred bytes. + */ +#define IPMI_MAX_PEL_SIZE 0x800 + +struct ipmi_backend; +struct ipmi_msg { + /* Can be used by command implementations to track requests */ + struct list_node link; + + struct ipmi_backend *backend; + uint8_t netfn; + uint8_t cmd; + uint8_t cc; + + /* Called when a response is received to the ipmi message */ + void (*complete)(struct ipmi_msg *); + + /* Called if non-NULL when the ipmi layer detects an error */ + void (*error)(struct ipmi_msg *); + void *user_data; + + uint8_t req_size; + uint8_t resp_size; + uint8_t *data; +}; + +struct ipmi_backend { + uint64_t opal_event_ipmi_recv; + struct ipmi_msg *(*alloc_msg)(size_t, size_t); + void (*free_msg)(struct ipmi_msg *); + int (*queue_msg)(struct ipmi_msg *); + int (*queue_msg_head)(struct ipmi_msg *); + int (*dequeue_msg)(struct ipmi_msg *); + void (*disable_retry)(struct ipmi_msg *); + /* + * When processing a synchronous IPMI message, pollers may not run, and + * neither may timers (as the synchronous IPMI message may be being + * done with locks held, which a timer may then try to also take). + * + * So, ensure we have a way to drive any state machines that an IPMI + * backend may neeed to crank to ensure forward progress. + */ + void (*poll)(void); +}; + +extern struct ipmi_backend *ipmi_backend; + +/* Initialise the IPMI interface */ +void ipmi_init(void); + +bool ipmi_present(void); + +void ipmi_free_msg(struct ipmi_msg *msg); + +struct ipmi_msg *ipmi_mkmsg_simple(uint32_t code, void *req_data, size_t req_size); +struct ipmi_msg *ipmi_mkmsg(int interface, uint32_t code, + void (*complete)(struct ipmi_msg *), + void *user_data, void *req_data, size_t req_size, + size_t resp_size); + +/* Initialise a previously allocated message with the required +fields. The caller must ensure the message is large enough to hold the +request and response data. */ +void ipmi_init_msg(struct ipmi_msg *msg, int interface, + uint32_t code, void (*complete)(struct ipmi_msg *), + void *user_data, size_t req_size, size_t resp_size); + +/* called by backend code to indicate a SMS_ATN event */ +void ipmi_sms_attention(void); + +/* Add an ipmi message to the queue */ +int ipmi_queue_msg(struct ipmi_msg *msg); + +/* Add an ipmi message to the start of the queue */ +int ipmi_queue_msg_head(struct ipmi_msg *msg); + +/* Synchronously send an ipmi message. This won't return until the + * messages callback has been called. */ +void ipmi_queue_msg_sync(struct ipmi_msg *msg); + +/* Removes the message from the list, queued previously */ +int ipmi_dequeue_msg(struct ipmi_msg *msg); + +/* Process a completed message */ +void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg); + +/* 28.3 Chassis Control Command. Changes the power state of the P8. */ +int ipmi_chassis_control(uint8_t request); + +/* 20.7 ACPI Power State Command (without the ACPI part). Informative only, + * use chassis control to perform power off and reboot. */ +int ipmi_set_power_state(uint8_t system, uint8_t device); + +/* 35.17 Set Sensor Reading Command */ +int ipmi_set_sensor(uint8_t sensor, uint8_t *reading, size_t len); +int ipmi_set_fw_progress_sensor(uint8_t state); + +/* Register a backend with the ipmi core. Currently we only support one. */ +void ipmi_register_backend(struct ipmi_backend *backend); + +/* Allocate IPMI SEL panic message */ +void ipmi_sel_init(void); + +/* Register SEL handler with IPMI core */ +int ipmi_sel_register(uint8_t oem_cmd, + void (*handler)(uint8_t data, void *context), + void *context); + +/* Register rtc ipmi commands with as opal callbacks. */ +void ipmi_rtc_init(void); + +/* Register ipmi host interface access callbacks */ +void ipmi_opal_init(void); + +/* Populate fru data */ +void ipmi_fru_init(uint8_t fru_dev_id); + +/* Commit an error log to the bmc using the OEM add eSEL commands */ +struct errorlog; +int ipmi_elog_commit(struct errorlog *elog_buf); + +/* Callback to parse an OEM SEL message */ +void ipmi_parse_sel(struct ipmi_msg *msg); + +/* Starts the watchdog timer */ +void ipmi_wdt_init(void); + +/* Stop the wdt */ +void ipmi_wdt_stop(void); + +/* Reset the watchdog timer. Does not return until the timer has been + * reset and does not schedule future resets. */ +void ipmi_wdt_final_reset(void); + +/* Discover id of settable ipmi sensors */ +void ipmi_sensor_init(void); + +/* Get sensor number for given sensor type */ +uint8_t ipmi_get_sensor_number(uint8_t sensor_type); + +/* Set the boot count once the OS is up and running */ +int ipmi_set_boot_count(void); + +/* Terminate immediate */ +void __attribute__((noreturn)) ipmi_terminate(const char *msg); + +/* Get BMC firmware info */ +extern int ipmi_get_bmc_info_request(void); + +/* Add BMC firmware info to device tree */ +extern void ipmi_dt_add_bmc_info(void); + +/* Get BMC Boot Options info (specifically OEM param 0x62) */ +int ipmi_get_chassis_boot_opt_request(void); + +/* Get OEM Boot Option 0x62 for SBE validation flag */ +int ipmi_chassis_check_sbe_validation(void); + +#endif diff --git a/roms/skiboot/include/lock.h b/roms/skiboot/include/lock.h new file mode 100644 index 000000000..244adeaa4 --- /dev/null +++ b/roms/skiboot/include/lock.h @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __LOCK_H +#define __LOCK_H + +#include <stdbool.h> +#include <processor.h> +#include <cmpxchg.h> +#include <ccan/list/list.h> +#include <ccan/str/str.h> + +#ifdef DEBUG_LOCKS_BACKTRACE +#include <stack.h> + +#define LOCKS_BACKTRACE_MAX_ENTS 60 +#endif + +struct lock { + /* Lock value has bit 63 as lock bit and the PIR of the owner + * in the top 32-bit + */ + uint64_t lock_val; + + /* + * Set to true if lock is involved in the console flush path + * in which case taking it will suspend console flushing + */ + bool in_con_path; + + /* file/line of lock owner */ + const char *owner; + +#ifdef DEBUG_LOCKS_BACKTRACE + struct bt_entry bt_buf[LOCKS_BACKTRACE_MAX_ENTS]; + struct bt_metadata bt_metadata; +#endif + + /* linkage in per-cpu list of owned locks */ + struct list_node list; +}; + +/* Initializer... not ideal but works for now. If we need different + * values for the fields and/or start getting warnings we'll have to + * play macro tricks + */ +#define LOCK_UNLOCKED { 0 } + +/* Note vs. libc and locking: + * + * The printf() family of + * functions use stack based t buffers and call into skiboot + * underlying read() and write() which use a console lock. + * + * The underlying FSP console code will thus operate within that + * console lock. + * + * The libc does *NOT* lock stream buffer operations, so don't + * try to scanf() from the same FILE from two different processors. + * + * FSP operations are locked using an FSP lock, so all processors + * can safely call the FSP API + * + * Note about ordering: + * + * lock() is a full memory barrier. unlock() is a lwsync + * + */ + +extern bool bust_locks; + +static inline void init_lock(struct lock *l) +{ + *l = (struct lock)LOCK_UNLOCKED; +} + +#define LOCK_CALLER __FILE__ ":" stringify(__LINE__) + +#define try_lock(l) try_lock_caller(l, LOCK_CALLER) +#define lock(l) lock_caller(l, LOCK_CALLER) +#define lock_recursive(l) lock_recursive_caller(l, LOCK_CALLER) + +extern bool try_lock_caller(struct lock *l, const char *caller); +extern void lock_caller(struct lock *l, const char *caller); +extern void unlock(struct lock *l); + +extern bool lock_held_by_me(struct lock *l); + +/* The debug output can happen while the FSP lock, so we need some kind + * of recursive lock support here. I don't want all locks to be recursive + * though, thus the caller need to explicitly call lock_recursive which + * returns false if the lock was already held by this cpu. If it returns + * true, then the caller shall release it when done. + */ +extern bool lock_recursive_caller(struct lock *l, const char *caller); + +/* Called after per-cpu data structures are available */ +extern void init_locks(void); + +/* Dump the list of locks held by this CPU */ +extern void dump_locks_list(void); + +/* Clean all locks held by CPU (and warn if any) */ +extern void drop_my_locks(bool warn); + +#endif /* __LOCK_H */ diff --git a/roms/skiboot/include/lpc-mbox.h b/roms/skiboot/include/lpc-mbox.h new file mode 100644 index 000000000..5883cc305 --- /dev/null +++ b/roms/skiboot/include/lpc-mbox.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017-2018 IBM Corp. */ + +#ifndef __LPC_MBOX_H +#define __LPC_MBOX_H + +#include <hiomap.h> +#include <opal.h> +#include <ccan/endian/endian.h> + +#define BMC_MBOX_ARGS_REGS 11 +#define BMC_MBOX_READ_REGS 16 +#define BMC_MBOX_WRITE_REGS 13 + +#define MBOX_C_RESET_STATE HIOMAP_C_RESET +#define MBOX_C_GET_MBOX_INFO HIOMAP_C_GET_INFO +#define MBOX_C_GET_FLASH_INFO HIOMAP_C_GET_FLASH_INFO +#define MBOX_C_CREATE_READ_WINDOW HIOMAP_C_CREATE_READ_WINDOW +#define MBOX_C_CLOSE_WINDOW HIOMAP_C_CLOSE_WINDOW +#define MBOX_C_CREATE_WRITE_WINDOW HIOMAP_C_CREATE_WRITE_WINDOW +#define MBOX_C_MARK_WRITE_DIRTY HIOMAP_C_MARK_DIRTY +#define MBOX_C_WRITE_FLUSH HIOMAP_C_FLUSH +#define MBOX_C_BMC_EVENT_ACK HIOMAP_C_ACK +#define MBOX_C_MARK_WRITE_ERASED HIOMAP_C_ERASE +#define MBOX_C_GET_FLASH_NAME HIOMAP_C_DEVICE_NAME +#define MBOX_C_MARK_LOCKED HIOMAP_C_LOCK +#define MBOX_COMMAND_COUNT 12 + +#define MBOX_R_SUCCESS 0x01 +#define MBOX_R_PARAM_ERROR 0x02 +#define MBOX_R_WRITE_ERROR 0x03 +#define MBOX_R_SYSTEM_ERROR 0x04 +#define MBOX_R_TIMEOUT 0x05 +#define MBOX_R_BUSY 0x06 +#define MBOX_R_WINDOW_ERROR 0x07 +#define MBOX_R_SEQ_ERROR 0x08 +#define MBOX_R_LOCKED 0x09 + +#define MBOX_ATTN_ACK_MASK HIOMAP_E_ACK_MASK +#define MBOX_ATTN_BMC_REBOOT HIOMAP_E_PROTOCOL_RESET +#define MBOX_ATTN_BMC_WINDOW_RESET HIOMAP_E_WINDOW_RESET +#define MBOX_ATTN_BMC_FLASH_LOST HIOMAP_E_FLASH_LOST +#define MBOX_ATTN_BMC_DAEMON_READY HIOMAP_E_DAEMON_READY + +/* Default poll interval before interrupts are working */ +#define MBOX_DEFAULT_POLL_MS 200 + +struct bmc_mbox_msg { + uint8_t command; + uint8_t seq; + uint8_t args[BMC_MBOX_ARGS_REGS]; + uint8_t response; + uint8_t host; + uint8_t bmc; +}; + +int bmc_mbox_enqueue(struct bmc_mbox_msg *msg, unsigned int timeout_sec); +int bmc_mbox_register_callback(void (*callback)(struct bmc_mbox_msg *msg, void *priv), + void *drv_data); +int bmc_mbox_register_attn(void (*callback)(uint8_t bits, void *priv), + void *drv_data); +uint8_t bmc_mbox_get_attn_reg(void); +#endif /* __LPC_MBOX_H */ diff --git a/roms/skiboot/include/lpc.h b/roms/skiboot/include/lpc.h new file mode 100644 index 000000000..b641aa4e6 --- /dev/null +++ b/roms/skiboot/include/lpc.h @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __LPC_H +#define __LPC_H + +#include <opal.h> +#include <ccan/endian/endian.h> + +/* Note about LPC interrupts + * + * LPC interrupts come in two categories: + * + * - External device LPC interrupts + * - Error interrupts generated by the LPC controller + * + * The former is implemented differently depending on whether + * you are using Murano/Venice or Naples. + * + * The former two chips don't have a pin to deserialize the LPC + * SerIRQ protocol, so the only source of LPC device interrupts + * is an external interrupt pin, which is usually connected to a + * CPLD which deserializes SerIRQ. + * + * So in that case, we get external interrupts from the PSI which + * are in effect the "OR" of all the active LPC interrupts. + * + * The error interrupt generated by the LPC controllers however + * are internally routed normally to the PSI bridge and muxed with + * the I2C interrupts. + * + * On Naples, there is a pin to deserialize SerIRQ, so the individual + * LPC device interrupts (up to 19) are represented in the same status + * and mask register as the LPC error interrupts. They are still all + * then turned into a single XIVE interrupts in the PSI however, muxed + * with the I2C. + * + * In order to more/less transparently handle this, we let individual + * "drivers" register for specific LPC interrupts. On Naples, the handlers + * will be called individually based on what has been demuxed by the + * controller. On Venice/Murano, all the handlers will be called on + * every external interrupt. The platform is responsible of calling + * lpc_all_interrupts() from the platform external interrupt handler. + */ + +/* Routines for accessing the LPC bus on Power8 */ + +extern void lpc_init(void); +extern void lpc_init_interrupts(void); +extern void lpc_finalize_interrupts(void); + +/* Check for a default bus */ +extern bool lpc_present(void); + +/* Return of LPC is currently usable. This can be false if the caller + * currently holds a lock that would make it unsafe, or the LPC bus + * is known to be in some error condition (TBI). + */ +extern bool lpc_ok(void); + +/* Handle the interrupt from the LPC controller */ +extern void lpc_interrupt(uint32_t chip_id); + +/* On P9, we have a different route for SerIRQ */ +extern void lpc_serirq(uint32_t chip_id, uint32_t index); + +/* Call all external handlers */ +extern void lpc_all_interrupts(uint32_t chip_id); + +/* Register/deregister handler */ +struct lpc_client { + /* Callback on LPC reset */ + void (*reset)(uint32_t chip_id); + + /* Callback on LPC interrupt */ + void (*interrupt)(uint32_t chip_id, uint32_t irq_msk); + /* Bitmask of interrupts this client is interested in + * Note: beware of ordering, use LPC_IRQ() macro + */ + uint32_t interrupts; +#define LPC_IRQ(n) (0x80000000 >> (n)) +}; + +extern void lpc_register_client(uint32_t chip_id, const struct lpc_client *clt, + uint32_t policy); + +/* Return the policy for a given serirq */ +extern unsigned int lpc_get_irq_policy(uint32_t chip_id, uint32_t psi_idx); + +/* Default bus accessors that perform error logging */ +extern int64_t lpc_write(enum OpalLPCAddressType addr_type, uint32_t addr, + uint32_t data, uint32_t sz); +extern int64_t lpc_read(enum OpalLPCAddressType addr_type, uint32_t addr, + uint32_t *data, uint32_t sz); + +/* + * LPC bus accessors that return errors as required but do not log the failure. + * Useful if the caller wants to test the presence of a device on the LPC bus. + */ +extern int64_t lpc_probe_write(enum OpalLPCAddressType addr_type, uint32_t addr, + uint32_t data, uint32_t sz); +extern int64_t lpc_probe_read(enum OpalLPCAddressType addr_type, uint32_t addr, + uint32_t *data, uint32_t sz); + +/* Mark LPC bus as used by console */ +extern void lpc_used_by_console(void); + +/* + * Simplified big endian FW accessors + */ +static inline int64_t lpc_fw_read32(uint32_t *val, uint32_t addr) +{ + return lpc_read(OPAL_LPC_FW, addr, val, 4); +} + +static inline int64_t lpc_fw_write32(uint32_t val, uint32_t addr) +{ + return lpc_write(OPAL_LPC_FW, addr, val, 4); +} + + +/* + * Simplified Little Endian IO space accessors + * + * Note: We do *NOT* handle unaligned accesses + */ + +static inline void lpc_outb(uint8_t data, uint32_t addr) +{ + lpc_write(OPAL_LPC_IO, addr, data, 1); +} + +static inline uint8_t lpc_inb(uint32_t addr) +{ + uint32_t d32; + int64_t rc = lpc_read(OPAL_LPC_IO, addr, &d32, 1); + return (rc == OPAL_SUCCESS) ? d32 : 0xff; +} + +static inline void lpc_outw(uint16_t data, uint32_t addr) +{ + lpc_write(OPAL_LPC_IO, addr, cpu_to_le16(data), 2); +} + +static inline uint16_t lpc_inw(uint32_t addr) +{ + uint32_t d32; + int64_t rc = lpc_read(OPAL_LPC_IO, addr, &d32, 2); + return (rc == OPAL_SUCCESS) ? le16_to_cpu(d32) : 0xffff; +} + +static inline void lpc_outl(uint32_t data, uint32_t addr) +{ + lpc_write(OPAL_LPC_IO, addr, cpu_to_le32(data), 4); +} + +static inline uint32_t lpc_inl(uint32_t addr) +{ + uint32_t d32; + int64_t rc = lpc_read(OPAL_LPC_IO, addr, &d32, 4); + return (rc == OPAL_SUCCESS) ? le32_to_cpu(d32) : 0xffffffff; +} + +#endif /* __LPC_H */ diff --git a/roms/skiboot/include/mem-map.h b/roms/skiboot/include/mem-map.h new file mode 100644 index 000000000..9250a63d5 --- /dev/null +++ b/roms/skiboot/include/mem-map.h @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __MEM_MAP_H +#define __MEM_MAP_H + +/* This is our main offset for relocation. All our buffers + * are offset from that and our code relocates itself to + * that location + */ +#define SKIBOOT_BASE 0x30000000 + +/* Stack size set to 32K, 16K for general stack and 16K for an emergency + * stack. + */ +#define STACK_SHIFT 15 +#define STACK_SIZE (1 << STACK_SHIFT) + +/* End of the exception region we copy from 0x0. 0x0-0x100 will have + * IPL data and is not actually for exception vectors. + */ +#define EXCEPTION_VECTORS_END 0x3000 + +#define NACA_OFF 0x4000 + +/* The NACA and other stuff in head.S need to be at the start: we + * give it 64k before placing the SPIRA and related data. + */ +#define SPIRA_OFF 0x00010000 +#define SPIRA_SIZE 0x400 +#define SPIRAH_OFF 0x00010400 +#define SPIRAH_SIZE 0x300 + +#define PROC_DUMP_AREA_OFF (SPIRAH_OFF + SPIRAH_SIZE) +#define PROC_DUMP_AREA_SIZE 0x100 + +/* Actual SPIRA size is lesser than 1K (presently 0x340 bytes). + * Use 1K for legacy SPIRA. + * + * SPIRA-H is lesser than 768 bytes (presently we use 288 bytes) + * Use 768 bytes for SPIRAH. + * + * Use 256 bytes for processor dump area. (presently we use + * sizeof(proc_dump_area) = 0x30 bytes). + * + * Then follow with for proc_init_data (aka PROCIN). + * These need to be at fixed addresses in case we're ever little + * endian: linker can't endian reverse a pointer for us. Text, data + * et. al. follows this. + */ +#define PROCIN_OFF (SPIRA_OFF + 0x800) + +/* Initial MDST and MDDT tables like PROCIN, we need fixed addresses, + * we leave a 2k gap for PROCIN + */ +#define MDST_TABLE_OFF (SPIRA_OFF + 0x1000) +#define MDST_TABLE_SIZE 0x400 + +#define MDDT_TABLE_OFF (SPIRA_OFF + 0x1400) +#define MDDT_TABLE_SIZE 0x400 + +/* Like MDST and MDDT, we need fixed address for CPU control header. + * We leave a 2k gap for MDST. CPU_CTL table is of size ~4k + */ +#define CPU_CTL_OFF (SPIRA_OFF + 0x1800) + +/* We keep a gap of 5M for skiboot text & bss for now. We will + * then we have our heap which goes up to base + 14M (so 11M for + * now, though we can certainly reduce that a lot). + * + * Ideally, we should fix the heap end and use _end to basically + * initialize our heap so that it covers anything from _end to + * that heap end, avoiding wasted space. + * + * That's made a bit tricky however due to how we create those + * regions statically in mem_region.c, but still on the list of + * things to improve. + * + * As of A Long Time Ago (2014/4/6), we used approc 512K for skiboot + * core and 2M of heap on a 1 socket machine. + * + * As of still a Long Time Ago (2015/5/7) we used approx 800k for skiboot, + * 500k HEAP for mambo boot. + * + * As of mid-2019, a 2 socket Romulus uses ~4MB heap. + */ +#define HEAP_BASE (SKIBOOT_BASE + 0x00600000) +#define HEAP_SIZE 0x00a00000 + +/* This is the location of our console buffer at base + 16M */ +#define INMEM_CON_START (SKIBOOT_BASE + 0x01000000) +#define INMEM_CON_LEN 0x100000 + +/* This is the location of HBRT console buffer at base + 17M */ +#define HBRT_CON_START (SKIBOOT_BASE + 0x01100000) +#define HBRT_CON_LEN 0x100000 + +/* Tell FSP to put the init data at base + 20M, allocate 8M */ +#define SPIRA_HEAP_BASE (SKIBOOT_BASE + 0x01200000) +#define SPIRA_HEAP_SIZE 0x00800000 + +/* This is our PSI TCE table. It's 256K entries on P8 */ +#define PSI_TCE_TABLE_BASE (SKIBOOT_BASE + 0x01a00000) +#define PSI_TCE_TABLE_SIZE 0x00200000UL + +/* This is our dump result table after MPIPL. Hostboot will write to this + * memory after moving memory content from source to destination memory. + */ +#define MDRT_TABLE_BASE (SKIBOOT_BASE + 0x01c00000) +#define MDRT_TABLE_SIZE 0x00008000 + +/* This is our dump metadata area. We will use this memory to save metadata + * (like crashing CPU details, payload tags) before triggering MPIPL. + */ +#define DUMP_METADATA_AREA_BASE (SKIBOOT_BASE + 0x01c08000) +#define DUMP_METADATA_AREA_SIZE 0x8000 + +/* Total size of the above area + * + * (Ensure this has at least a 64k alignment) + */ +#define SKIBOOT_SIZE 0x01c10000 + +/* We start laying out the CPU stacks from here, indexed by PIR + * each stack is STACK_SIZE in size (naturally aligned power of + * two) and the bottom of the stack contains the cpu thread + * structure for the processor, so it can be obtained by a simple + * bit mask from the stack pointer. Within the CPU stack is divided + * into a normal and emergency stack to cope with a single level of + * re-entrancy. + * + * The size of this array is dynamically determined at boot time + */ +#define CPU_STACKS_BASE (SKIBOOT_BASE + SKIBOOT_SIZE) + +/* + * Address at which we load the kernel LID. This is also where + * we expect a passed-in kernel if booting without FSP and + * without a built-in kernel. + */ +#define KERNEL_LOAD_BASE ((void *)0x20000000) +#define KERNEL_LOAD_SIZE 0x08000000 + +#define INITRAMFS_LOAD_BASE KERNEL_LOAD_BASE + KERNEL_LOAD_SIZE +#define INITRAMFS_LOAD_SIZE 0x08000000 + +/* Size allocated to build the device-tree */ +#define DEVICE_TREE_MAX_SIZE 0x80000 + + +#endif /* __MEM_MAP_H */ diff --git a/roms/skiboot/include/mem_region-malloc.h b/roms/skiboot/include/mem_region-malloc.h new file mode 100644 index 000000000..271311b2c --- /dev/null +++ b/roms/skiboot/include/mem_region-malloc.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __MEM_REGION_MALLOC_H +#define __MEM_REGION_MALLOC_H + +#include <compiler.h> + +#define __loc2(line) #line +#define __loc(line) __loc2(line) +#define __location__ __FILE__ ":" __loc(__LINE__) + +void *__malloc(size_t size, const char *location) __warn_unused_result; +void *__zalloc(size_t size, const char *location) __warn_unused_result; +void *__realloc(void *ptr, size_t size, const char *location) __warn_unused_result; +void __free(void *ptr, const char *location); +void *__memalign(size_t boundary, size_t size, const char *location) __warn_unused_result; + +#define malloc(size) __malloc(size, __location__) +#define zalloc(size) __zalloc(size, __location__) +#define calloc(nmemb, size) __zalloc(((nmemb) * (size)), __location__) +#define realloc(ptr, size) __realloc(ptr, size, __location__) +#define free(ptr) __free(ptr, __location__) +#define memalign(boundary, size) __memalign(boundary, size, __location__) + +void *__local_alloc(unsigned int chip, size_t size, size_t align, + const char *location) __warn_unused_result; +#define local_alloc(chip_id, size, align) \ + __local_alloc((chip_id), (size), (align), __location__) + +#endif /* __MEM_REGION_MALLOC_H */ diff --git a/roms/skiboot/include/mem_region.h b/roms/skiboot/include/mem_region.h new file mode 100644 index 000000000..3e3818a66 --- /dev/null +++ b/roms/skiboot/include/mem_region.h @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __MEMORY_REGION +#define __MEMORY_REGION +#include <ccan/list/list.h> +#include <stdint.h> + +#include <lock.h> + +enum mem_region_type { + /* ranges allocatable by mem_alloc: this will be most of memory */ + REGION_SKIBOOT_HEAP, + + /* ranges allocatable by mem_alloc but shrunk (e.g. whole memory) */ + REGION_MEMORY, + + /* ranges used explicitly for skiboot, but not allocatable. eg .text */ + REGION_SKIBOOT_FIRMWARE, + + /* ranges reserved before skiboot init, eg HBRT memory */ + REGION_FW_RESERVED, + + /* ranges reserved, eg HW framebuffer */ + REGION_RESERVED, + + /* ranges available for the OS, created by mem_region_release_unused */ + REGION_OS, +}; + +/* An area of physical memory. */ +struct mem_region { + struct list_node list; + const char *name; + uint64_t start, len; + struct dt_node *node; + enum mem_region_type type; + struct list_head free_list; + struct lock free_list_lock; +}; + +extern struct lock mem_region_lock; +extern unsigned long top_of_ram; + +void *mem_alloc(struct mem_region *region, size_t size, size_t align, + const char *location); +void mem_free(struct mem_region *region, void *mem, + const char *location); +bool mem_resize(struct mem_region *region, void *mem, size_t len, + const char *location); +size_t mem_allocated_size(const void *ptr); +bool mem_check(const struct mem_region *region); +bool mem_check_all(void); +void mem_region_release_unused(void); +void start_mem_region_clear_unused(void); +void wait_mem_region_clear_unused(void); +int64_t mem_dump_free(void); +void mem_dump_allocs(void); + +/* Specifically for working on the heap. */ +extern struct mem_region skiboot_heap; + +void mem_region_init(void); +void mem_region_add_dt_reserved(void); + +/* Mark memory as reserved */ +void mem_reserve_fw(const char *name, uint64_t start, uint64_t len); +void mem_reserve_hwbuf(const char *name, uint64_t start, uint64_t len); + +struct mem_region *find_mem_region(const char *name); + +bool mem_range_is_reserved(uint64_t start, uint64_t size); + +/* Read-only memory checksum */ +bool verify_romem(void); + +#endif /* __MEMORY_REGION */ diff --git a/roms/skiboot/include/npu-regs.h b/roms/skiboot/include/npu-regs.h new file mode 100644 index 000000000..38d53c9fe --- /dev/null +++ b/roms/skiboot/include/npu-regs.h @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __NPU_REGS_H +#define __NPU_REGS_H + +/* Size of a single link */ +#define NPU_LINK_SIZE 0x40 + +/* Link registers */ +#define NX_PB_ERR_RPT_0 0x00 +#define NX_PB_ERR_RPT_1 0x01 +#define NX_MMIO_BAR_0 0x02 +#define NX_MMIO_BAR_1 0x03 +#define NX_MMIO_BAR_BASE PPC_BITMASK(14,51) +#define NX_MMIO_BAR_ENABLE PPC_BIT(52) +#define NX_MMIO_BAR_SIZE PPC_BITMASK(53,55) +#define NX_NODAL_BAR0 0x04 +#define NX_NODAL_BAR1 0x05 +#define NX_NODAL_BAR_ENABLE PPC_BIT(0) +#define NX_NODAL_BAR_MASK PPC_BITMASK(1,14) +#define NX_NODAL_BAR_BASE PPC_BITMASK(15,32) +#define NX_GROUP_BAR0 0x06 +#define NX_GROUP_BAR1 0x07 +#define NX_GROUP_BAR_ENABLE PPC_BIT(0) +#define NX_GROUP_BAR_MASK PPC_BITMASK(1,14) +#define NX_GROUP_BAR_BASE PPC_BITMASK(15,32) +#define NX_EPSILON_COUN 0x08 +#define NX_EPSILON_COUN_DISABLE PPC_BIT(6) +#define NX_MISC_CONTROL 0x09 +#define NX_PB_DEBUG 0x0a +#define NX_PB_ECC 0x0b +#define NX_DEBUG_SNAPSHOT_0 0x0c +#define NX_DEBUG_SNAPSHOT_1 0x0d +#define NX_CS_CTL 0x0e +#define NX_CONFIG_CQ 0x0f +#define NX_MRBO0 0x10 +#define NX_MRBO1 0x11 +#define NX_AS_CMD_CFG 0x12 +#define NX_NP_BUID 0x13 +#define NP_BUID_ENABLE PPC_BIT(0) +#define NP_BUID_BASE PPC_BITMASK(1,15) +#define NP_IRQ_LEVELS PPC_BITMASK(16,23) +#define NP_BUID_MASK PPC_BITMASK(24,32) +#define NX_TL_CMD_CR 0x20 +#define NX_TL_CMD_D_CR 0x21 +#define NX_TL_RSP_CR 0x22 +#define NX_TL_RSP_D_CR 0x23 +#define NX_DL_REG_ADDR 0x24 +#define NX_DL_REG_DATA 0x25 +#define NX_NTL_CONTROL 0x26 +#define NX_NTL_PMU_CONTROL 0x27 +#define NX_NTL_PMU_COUNT 0x28 +#define NX_NTL_ER_HOLD 0x29 +#define NX_NTL_FST_ERR 0x2a +#define NX_NTL_ECC 0x2b +#define NX_NTL_FST_MSK 0x2c + +/* NP AT register */ +#define NX_FIR 0x00 +#define NX_FIR_CLEAR 0x01 +#define NX_FIR_SET 0x02 +#define NX_FIR_MASK 0x03 +#define NX_FIR_MASK_CLR 0x04 +#define NX_FIR_MASK_SET 0x05 +#define NX_FIR_ACTION0 0x06 +#define NX_FIR_ACTION1 0x07 +#define NX_FIR_WOF 0x08 +#define NX_AT_PMU_CTRL 0x26 +#define NX_AT_PMU_CNT 0x27 +#define NX_AT_ERR_HOLD 0x28 +#define NX_AT_ERR_HOLD_RESET PPC_BIT(63) +#define NX_AT_DEBUG 0x29 +#define NX_AT_ECC 0x2a +#define NX_BAR 0x2b + +/* AT MMIO registers */ +#define NPU_LSI_SOURCE_ID 0x00100 +#define NPU_LSI_SRC_ID_BASE PPC_BITMASK(5,11) +#define NPU_DMA_CHAN_STATUS 0x00110 +#define NPU_INTREP_TIMER 0x001f8 +#define NPU_DMARD_SYNC 0x00200 +#define NPU_DMARD_SYNC_START_RD PPC_BIT(0) +#define NPU_DMARD_SYNC_RD PPC_BIT(1) +#define NPU_DMARD_SYNC_START_WR PPC_BIT(2) +#define NPU_DMARD_SYNC_WR PPC_BIT(3) +#define NPU_TCE_KILL 0x00210 +#define NPU_IODA_ADDR 0x00220 +#define NPU_IODA_AD_AUTOINC PPC_BIT(0) +#define NPU_IODA_AD_TSEL PPC_BITMASK(11,15) +#define NPU_IODA_AD_TADR PPC_BITMASK(54,63) +#define NPU_IODA_DATA0 0x00228 +#define NPU_XIVE_UPD 0x00248 +#define NPU_GEN_CAP 0x00250 +#define NPU_TCE_CAP 0x00258 +#define NPU_INT_CAP 0x00260 +#define NPU_EEH_CAP 0x00268 +#define NPU_VR 0x00800 +#define NPU_CTRLR 0x00810 +#define NPU_TCR 0x00880 +#define NPU_Q_DMA_R 0x00888 +#define NPU_AT_ESR 0x00c80 +#define NPU_AT_FESR 0x00c88 +#define NPU_AT_LR_ER 0x00c98 +#define NPU_AT_SI_ER 0x00ca0 +#define NPU_AT_FR_ER 0x00ca8 +#define NPU_AT_FE_ER 0x00cb0 +#define NPU_AT_ESMR 0x00cd0 +#define NPU_AT_FESMR 0x00cd8 +#define NPU_AT_I_LR0 0x00d00 +#define NPU_AT_I_LR1 0x00d08 +#define NPU_AT_I_LR2 0x00d10 +#define NPU_AT_I_LR3 0x00d18 + +/* AT */ +#define NPU_AT_SCOM_OFFSET 0x180 + +/* NTL */ +#define TL_CMD_CR 0x10000 +#define TL_CMD_D_CR 0x10008 +#define TL_RSP_CR 0x10010 +#define TL_RSP_D_CR 0x10018 +#define NTL_CONTROL 0x10020 +#define NTL_CONTROL_RESET PPC_BIT(0) + +/* IODA tables */ +#define NPU_IODA_TBL_LIST 1 +#define NPU_IODA_TBL_LXIVT 2 +#define NPU_IODA_TBL_PCT 4 +#define NPU_IODA_TBL_PESTB 8 +#define NPU_IODA_TBL_TVT 9 +#define NPU_IODA_TBL_TCD 10 +#define NPU_IODA_TBL_TDR 11 +#define NPU_IODA_TBL_PESTB_ADDR 12 +#define NPU_IODA_TBL_EA 16 + +/* LXIVT */ +#define NPU_IODA_LXIVT_SERVER PPC_BITMASK(8,23) +#define NPU_IODA_LXIVT_PRIORITY PPC_BITMASK(24,31) + +/* PCT */ +#define NPU_IODA_PCT_LINK_ENABLED PPC_BIT(0) +#define NPU_IODA_PCT_PE PPC_BITMASK(2,3) + +/* TVT */ +#define NPU_IODA_TVT_TTA PPC_BITMASK(0,47) +#define NPU_IODA_TVT_LEVELS PPC_BITMASK(48,50) +#define NPU_IODA_TVE_1_LEVEL 0 +#define NPU_IODA_TVE_2_LEVELS 1 +#define NPU_IODA_TVE_3_LEVELS 2 +#define NPU_IODA_TVE_4_LEVELS 3 +#define NPU_IODA_TVT_SIZE PPC_BITMASK(51,55) +#define NPU_IODA_TVT_PSIZE PPC_BITMASK(59,63) + +/* NDL Registers */ +#define NDL_STATUS 0xfff0 +#define NDL_CONTROL 0xfff4 + +/* BAR Sizes */ +#define NX_MMIO_PL_SIZE 0x200000 +#define NX_MMIO_AT_SIZE 0x10000 +#define NX_MMIO_DL_SIZE 0x20000 + +/* Translates a PHY SCOM address to an MMIO offset */ +#define PL_MMIO_ADDR(reg) (((reg >> 32) & 0xfffffull) << 1) + +/* PHY register scom offsets & fields */ +#define RX_PR_CNTL_PL 0x0002180000000000UL +#define RX_PR_RESET PPC_BIT(63) + +#define TX_MODE1_PL 0x0004040000000000UL +#define TX_LANE_PDWN PPC_BIT(48) + +#define TX_MODE2_PL 0x00040c0000000000UL +#define TX_RXCAL PPC_BIT(57) +#define TX_UNLOAD_CLK_DISABLE PPC_BIT(56) + +#define TX_CNTL_STAT2 0x00041c0000000000UL +#define TX_FIFO_INIT PPC_BIT(48) + +#define RX_BANK_CONTROLS 0x0000f80000000000UL +#define RX_LANE_ANA_PDWN PPC_BIT(54) + +#define RX_MODE 0x0002000000000000UL +#define RX_LANE_DIG_PDWN PPC_BIT(48) + +#define RX_PR_MODE 0x0002100000000000UL +#define RX_PR_PHASE_STEP PPC_BITMASK(60, 63) + +#define RX_A_DAC_CNTL 0x0000080000000000UL +#define RX_PR_IQ_RES_SEL PPC_BITMASK(58, 60) + +#define RX_LANE_BUSY_VEC_0_15 0x000b000000000000UL +#define TX_FFE_TOTAL_2RSTEP_EN 0x000c240000000000UL +#define TX_FFE_TOTAL_ENABLE_P_ENC PPC_BITMASK(49,55) +#define TX_FFE_TOTAL_ENABLE_N_ENC PPC_BITMASK(57,63) +#define TX_FFE_PRE_2RSTEP_SEL 0x000c2c0000000000UL +#define TX_FFE_PRE_P_SEL_ENC PPC_BITMASK(51,54) +#define TX_FFE_PRE_N_SEL_ENC PPC_BITMASK(59,62) +#define TX_FFE_MARGIN_2RSTEP_SEL 0x000c34000000000UL +#define TX_FFE_MARGIN_PU_P_SEL_ENC PPC_BITMASK(51,55) +#define TX_FFE_MARGIN_PD_N_SEL_ENC PPC_BITMASK(59,63) +#define TX_IORESET_VEC_0_15 0x000d2c0000000000UL +#define TX_IMPCAL_PB 0x000f040000000000UL +#define TX_ZCAL_REQ PPC_BIT(49) +#define TX_ZCAL_DONE PPC_BIT(50) +#define TX_ZCAL_ERROR PPC_BIT(51) +#define TX_IMPCAL_NVAL_PB 0x000f0c0000000000UL +#define TX_ZCAL_N PPC_BITMASK(48,56) +#define TX_IMPCAL_PVAL_PB 0x000f140000000000UL +#define TX_ZCAL_P PPC_BITMASK(48,56) +#define RX_EO_STEP_CNTL_PG 0x0008300000000000UL +#define RX_EO_ENABLE_LATCH_OFFSET_CAL PPC_BIT(48) +#define RX_EO_ENABLE_CM_COARSE_CAL PPC_BIT(57) +#define RX_RUN_LANE_VEC_0_15 0x0009b80000000000UL +#define RX_RECAL_ABORT_VEC_0_15 0x0009c80000000000UL +#define RX_IORESET_VEC_0_15 0x0009d80000000000UL +#define RX_EO_RECAL_PG 0x000a800000000000UL +#define RX_INIT_DONE_VEC_0_15 0x000ac00000000000UL +#define TX_IMPCAL_SWO1_PB 0x000f240000000000UL +#define TX_ZCAL_SWO_EN PPC_BIT(48) +#define TX_IMPCAL_SWO2_PB 0x000f2c0000000000UL + +#endif /* __NPU_REGS_H */ diff --git a/roms/skiboot/include/npu.h b/roms/skiboot/include/npu.h new file mode 100644 index 000000000..50cc9c9fc --- /dev/null +++ b/roms/skiboot/include/npu.h @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2017 IBM Corp. */ + +#ifndef __NPU_H +#define __NPU_H + +#include <io.h> + +/* Number of PEs supported */ +#define NPU_NUM_OF_PES 4 + +/* Each brick has 2 MMIO BARs at the maximum. BAR0 is always used to + * map the 128KB TL/DL registers. BAR1 is used to map either the PL or + * the AT registers which are not exposed to the OS. + */ +#define NPU_BRICK_NUM_OF_BARS 2 +#define NPU_BRICK_TL_BAR_SIZE 0x20000 +#define NPU_BRICK_PL_BAR_SIZE 0x200000 + +/* Bytes of the emulated NPU PCI device config space. We are + * emulating PCI express device, not legacy one + */ +#define NPU_DEV_CFG_SIZE 0x100 + +/* Interrupt mapping + * + * NPU PHB doesn't support MSI interrupts. It only supports + * 8 LSI interrupts: [0, 3] for bricks' DL blocks. [4, 5] + * for reporting errors from DL blocks. [6, 7] for reporting + * errors from TL blocks, NPCQs and AT. + */ +#define NPU_LSI_IRQ_COUNT 8 +#define NPU_LSI_INT_DL0 0 +#define NPU_LSI_INT_DL1 1 +#define NPU_LSI_INT_DL2 2 +#define NPU_LSI_INT_DL3 3 +#define NPU_LSI_IRQ_MIN 0x7F0 +#define NPU_LSI_IRQ_MAX (NPU_LSI_IRQ_MIN + NPU_LSI_IRQ_COUNT - 1) +#define NPU_LSI_IRQ_BASE(chip, phb) (P8_CHIP_IRQ_PHB_BASE(chip, phb) | NPU_LSI_IRQ_MIN) +#define NPU_IRQ_NUM(irq) (irq & 0x7FF) + +/* NPU device capability descriptor. All PCI capabilities is + * organized as linked list. Each PCI capability has specific + * hook to populate when initializing NPU device. + */ +struct npu_dev; +struct npu_dev_cap { + uint16_t id; + uint16_t start; + uint16_t end; + struct npu_dev *dev; + void (*populate)(struct npu_dev_cap *cap); + struct list_node link; +}; + +struct npu_dev_bar { + uint32_t flags; + uint32_t xscom; + uint64_t base; + uint64_t size; + uint32_t bar_sz; + bool trapped; +}; + +/* Each device contains 2 links. The device will be exposed as + * standard PCIE device and the config space is emulated by skiboot. + */ +struct npu_dev { + uint32_t flags; + uint32_t index; + uint64_t xscom; + void *pl_base; + uint64_t pl_xscom_base; + struct npu_dev_bar bar; + struct phb *phb; + + /* The link@x node */ + struct dt_node *dt_node; + + /* PCI virtual device and the associated GPU device */ + struct pci_virt_device *pvd; + struct pci_device *pd; + struct npu *npu; + struct list_head capabilities; + + /* Which PHY lanes this device is associated with */ + uint16_t lane_mask; + + /* Used to store the currently running procedure number for + * this device. */ + uint16_t procedure_number; + + /* Used to store the step within a procedure that we are up + * to. */ + uint16_t procedure_step; + + /* Arbitrary data used by each procedure to track status. */ + uint64_t procedure_data; + + /* Used to timeout long running procedures. */ + unsigned long procedure_tb; + + uint32_t procedure_status; + + uint64_t pe_number; + + /* Used to associate the NPU device with GPU PCI devices */ + const char *slot_label; +}; + +/* NPU PHB descriptor */ +struct npu { + uint32_t flags; + uint32_t index; + uint32_t chip_id; + uint64_t xscom_base; + uint64_t at_xscom; + void *at_regs; + uint32_t base_lsi; + uint64_t mm_base; + uint64_t mm_size; + uint32_t total_devices; + struct npu_dev *devices; + + /* IODA cache */ + uint64_t lxive_cache[8]; + uint64_t pce_cache[6]; + uint64_t tve_cache[NPU_NUM_OF_PES]; + + bool tx_zcal_complete[2]; + bool fenced; + + struct phb phb; +}; + +static inline struct npu *phb_to_npu(struct phb *phb) +{ + return container_of(phb, struct npu, phb); +} + +static inline void npu_ioda_sel(struct npu *p, uint32_t table, + uint32_t addr, bool autoinc) +{ + out_be64(p->at_regs + NPU_IODA_ADDR, + (autoinc ? NPU_IODA_AD_AUTOINC : 0) | + SETFIELD(NPU_IODA_AD_TSEL, 0ul, table) | + SETFIELD(NPU_IODA_AD_TADR, 0ul, addr)); +} + +void npu_scom_init(struct npu_dev *dev); + +int64_t npu_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, + uint32_t offset, uint32_t len, uint32_t *data, + bool write); + +void npu_set_fence_state(struct npu *p, bool fence); +void npu_dev_procedure_reset(struct npu_dev *dev); + +#define NPUDBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \ + (p)->phb.opal_id, ##a) +#define NPUINF(p, fmt, a...) prlog(PR_INFO, "NPU%d: " fmt, \ + (p)->phb.opal_id, ##a) + +#define NPUDEVDBG(p, fmt, a...) NPUDBG((p)->npu, fmt, ##a) +#define NPUDEVINF(p, fmt, a...) NPUINF((p)->npu, fmt, ##a) + +#endif /* __NPU_H */ diff --git a/roms/skiboot/include/npu2-regs.h b/roms/skiboot/include/npu2-regs.h new file mode 100644 index 000000000..22f58a6af --- /dev/null +++ b/roms/skiboot/include/npu2-regs.h @@ -0,0 +1,791 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __NPU2_REGS_H +#define __NPU2_REGS_H + +struct npu2; +uint64_t npu2_read4(struct npu2 *p, uint64_t reg); +void npu2_write4(struct npu2 *p, uint64_t reg, uint64_t val); +uint64_t npu2_read(struct npu2 *p, uint64_t reg); +void npu2_write(struct npu2 *p, uint64_t reg, uint64_t val); +void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask); +uint64_t npu2_scom_read(uint64_t gcid, uint64_t scom_base, + uint64_t reg, uint64_t size); +void npu2_scom_write(uint64_t gcid, uint64_t scom_base, + uint64_t reg, uint64_t size, + uint64_t val); + +/* These aren't really NPU specific registers but we initialise them in NPU + * code */ +#define MCD0_BANK0_CN3 0x301100d +#define MCD1_BANK0_CN3 0x301140d +#define MCD_BANK_CN_VALID PPC_BIT(0) +#define MCD_BANK_CN_SIZE PPC_BITMASK(13,29) +#define MCD_BANK_CN_ADDR PPC_BITMASK(33,63) +#define PB_CENT_MODE 0x5011c0a +#define PB_CFG_CHIP_ADDR_EXTENSION_MASK_CENT PPC_BITMASK(42,48) + + +#define NPU2_REG_OFFSET(stack, block, offset) \ + (((stack) << 20) | ((block) << 16) | (offset)) + +#define NPU2_NTL_REG_OFFSET(ndev, offset) \ + NPU2_REG_OFFSET(NPU2_STACK_STCK_0 + ((ndev)->brick_index >> 1), \ + NPU2_BLOCK_NTL0 + ((ndev)->brick_index % 2)*2, offset) + +#define NPU2_NTLU_REG_OFFSET(ndev, offset) \ + NPU2_REG_OFFSET(NPU2_STACK_STCK_0U + ((ndev)->brick_index >> 1), \ + NPU2_BLOCK_NTL0 + ((ndev)->brick_index % 2)*2, offset) + +#define NPU2_DL_REG_OFFSET(ndev, offset) \ + NPU2_REG_OFFSET(((ndev)->brick_index >> 1), \ + 8 + ((ndev)->brick_index % 2)*2, offset) + +#define NPU2_SM_REG_OFFSET(ndev, sm, offset) \ + NPU2_REG_OFFSET(NPU2_STACK_STCK_0 + ((ndev)->brick_index >> 1), \ + NPU2_BLOCK_SM_0 + (sm), offset) + +/* Get the offset for this register */ +#define NPU2_REG(reg) \ + ((reg) & 0xffff) + +/* Get the stack number for this register */ +#define NPU2_REG_STACK(reg) \ + (((reg) >> 20) & 0xf) + +/* XTS tables */ +#define NPU2_XTS_BDF_MAP_SIZE 16 +#define NPU2_XTS_PID_MAP_SIZE 256 + +/* Stacks */ +#define NPU2_STACK_STCK_0U 0x0 +#define NPU2_STACK_STCK_1U 0x1 +#define NPU2_STACK_STCK_2U 0x2 +#define NPU2_STACK_STCK_0 0x4 +#define NPU2_STACK_STCK_1 0x5 +#define NPU2_STACK_STCK_2 0x6 +#define NPU2_STACK_MISC 0x7 +#define NPU2_STACK_ATSD 0x8 +#define NPU2_STACK_PHY00 0xc +#define NPU2_STACK_PHY01 0xd +#define NPU2_STACK_PHY10 0xe +#define NPU2_STACK_PHY11 0xf + +/* Link stack blocks */ +#define NPU2_BLOCK_SM_0 0x0 +#define NPU2_BLOCK_SM_1 0x1 +#define NPU2_BLOCK_SM_2 0x2 +#define NPU2_BLOCK_SM_3 0x3 +#define NPU2_BLOCK_CTL 0x4 +#define NPU2_BLOCK_DAT 0x5 +#define NPU2_BLOCK_NTL0 0x9 +#define NPU2_BLOCK_NTL1 0xb +#define NPU2_BLOCK_OTL0 0xc +#define NPU2_BLOCK_OTL1 0xd + +/* OpenCAPI blocks */ +#define NPU2_BLOCK_XSL 0xe + +/* MISC stack blocks */ +#define NPU2_BLOCK_ATS 0 +#define NPU2_BLOCK_XTS 1 +#define NPU2_BLOCK_MISC 2 + +/* ATSD stack blocks */ +#define NPU2_BLOCK_ATSD0 0 +#define NPU2_BLOCK_ATSD1 1 +#define NPU2_BLOCK_ATSD2 2 +#define NPU2_BLOCK_ATSD3 3 +#define NPU2_BLOCK_ATSD4 4 +#define NPU2_BLOCK_ATSD5 5 +#define NPU2_BLOCK_ATSD6 6 +#define NPU2_BLOCK_ATSD7 7 + +/* SM block registers */ +#define NPU2_CQ_SM_MISC_CFG0 0x000 +#define NPU2_CQ_SM_MISC_CFG0_CONFIG_ENABLE_PBUS PPC_BIT(38) +#define NPU2_CQ_SM_MISC_CFG0_CONFIG_OCAPI_MODE PPC_BIT(57) +#define NPU2_CQ_SM_MISC_CFG1 0x008 +#define NPU2_CQ_SM_MISC_CFG2 0x148 +#define NPU2_PB_EPSILON 0x010 +#define NPU2_TIMER_CFG 0x018 +#define NPU2_GPU0_MEM_BAR 0x020 +#define NPU2_GPU1_MEM_BAR 0x028 +#define NPU2_MEM_BAR_EN PPC_BIT(0) +#define NPU2_MEM_BAR_SEL_MEM PPC_BITMASK(1,2) +#define NPU2_MEM_BAR_GROUP PPC_BITMASK(3,6) +#define NPU2_MEM_BAR_CHIP PPC_BITMASK(7,9) +#define NPU2_MEM_BAR_NODE_ADDR PPC_BITMASK(10,21) +#define NPU2_MEM_BAR_ADDR PPC_BITMASK(0,21) +#define NPU2_MEM_BAR_POISON PPC_BIT(22) +#define NPU2_MEM_BAR_GRANULE PPC_BIT(23) +#define NPU2_MEM_BAR_BAR_SIZE PPC_BITMASK(24,27) +#define NPU2_MEM_BAR_MODE PPC_BITMASK(28,31) +#define NPU2_MEM_BAR_MASK PPC_BITMASK(33,39) +#define NPU2_PHY_BAR 0x030 +#define NPU2_PHY_BAR_ENABLE PPC_BIT(0) +#define NPU2_PHY_BAR_GROUP PPC_BITMASK(3,6) +#define NPU2_PHY_BAR_CHIP PPC_BITMASK(7,9) +#define NPU2_PHY_BAR_NODE_ADDR PPC_BITMASK(10,30) +#define NPU2_PHY_BAR_ADDR PPC_BITMASK(3,30) +#define NPU2_GENID_BAR 0x038 +#define NPU2_GENID_BAR_ENABLE PPC_BIT(0) +#define NPU2_GENID_BAR_GROUP PPC_BITMASK(3,6) +#define NPU2_GENID_BAR_CHIP PPC_BITMASK(7,9) +#define NPU2_GENID_BAR_NODE_ADDR PPC_BITMASK(10,35) +#define NPU2_GENID_BAR_ADDR PPC_BITMASK(3,35) +#define NPU2_GENID_BAR_POISON PPC_BIT(39) +#define NPU2_LOW_WATER_MARKS 0x040 +#define NPU2_LOW_WATER_MARKS_ENABLE_MACHINE_ALLOC PPC_BIT(51) +#define NPU2_HIGH_WATER_MARKS 0x048 +#define NPU2_RELAXED_ORDERING_CFG(n) (0x050 + (n)*8) +#define NPU2_RELAXED_ORDERING_SOURCE(n) (PPC_BITMASK(0,31) >> ((n)*32)) +#define NPU2_RELAXED_ORDERING_SOURCE_ENA PPC_BITMASK32(0,3) +#define NPU2_RELAXED_ORDERING_SOURCE_WRENA PPC_BIT32(0) +#define NPU2_RELAXED_ORDERING_SOURCE_RDENA PPC_BIT32(1) +#define NPU2_RELAXED_ORDERING_SOURCE_AWENA PPC_BIT32(2) +#define NPU2_RELAXED_ORDERING_SOURCE_ARENA PPC_BIT32(3) +#define NPU2_RELAXED_ORDERING_SOURCE_PECSEL PPC_BITMASK32(4,5) +#define NPU2_RELAXED_ORDERING_SOURCE_GRPCHP PPC_BITMASK32(6,9) +#define NPU2_RELAXED_ORDERING_SOURCE_WRMIN PPC_BITMASK32(10,14) +#define NPU2_RELAXED_ORDERING_SOURCE_WRMAX PPC_BITMASK32(15,19) +#define NPU2_RELAXED_ORDERING_SOURCE_RDMIN PPC_BITMASK32(20,25) +#define NPU2_RELAXED_ORDERING_SOURCE_RDMAX PPC_BITMASK32(26,31) +#define NPU2_RELAXED_ORDERING_CMD_CL_DMA_W PPC_BIT(0) +#define NPU2_RELAXED_ORDERING_CMD_CL_DMA_W_HP PPC_BIT(1) +#define NPU2_RELAXED_ORDERING_CMD_CL_DMA_INJ PPC_BIT(2) +#define NPU2_RELAXED_ORDERING_CMD_PR_DMA_INJ PPC_BIT(3) +#define NPU2_RELAXED_ORDERING_CMD_DMA_PR_W PPC_BIT(4) +#define NPU2_RELAXED_ORDERING_CMD_CL_RD_NC_F0 PPC_BIT(5) +#define NPU2_RELAXED_ORDERING_SOURCE4_RDENA PPC_BIT(29) +#define NPU2_NTL0_BAR 0x068 +#define NPU2_NTL1_BAR 0x070 +#define NPU2_NTL_BAR_ENABLE PPC_BIT(0) +#define NPU2_NTL_BAR_GROUP PPC_BITMASK(3,6) +#define NPU2_NTL_BAR_CHIP PPC_BITMASK(7,9) +#define NPU2_NTL_BAR_NODE_ADDR PPC_BITMASK(10,35) +#define NPU2_NTL_BAR_ADDR PPC_BITMASK(3,35) +#define NPU2_NTL_BAR_POISON PPC_BIT(36) +#define NPU2_NTL_BAR_SIZE PPC_BITMASK(39,43) +#define NPU2_PERF_CFG 0x078 +#define NPU2_INHIBIT_CFG 0x080 +#define NPU2_C_ERR_RPT_MSG0 0x088 +#define NPU2_C_ERR_RPT_MSG1 0x090 +#define NPU2_C_ERR_RPT_MSG2 0x098 +#define NPU2_C_ERR_RPT_MSG3 0x0A0 +#define NPU2_C_ERR_RPT_MSG4 0x0A8 +#define NPU2_CQ_SM_STATUS 0x0B0 +#define NPU2_C_ERR_RPT_FIRST0 0x0B8 +#define NPU2_C_ERR_RPT_FIRST1 0x0C0 +#define NPU2_C_ERR_RPT_FIRST2 0x0C8 +#define NPU2_C_ERR_RPT_MASK0 0x0D0 +#define NPU2_C_ERR_RPT_MASK1 0x0D8 +#define NPU2_C_ERR_RPT_MASK2 0x0E0 +#define NPU2_C_ERR_RPT_HOLD0 0x0E8 +#define NPU2_C_ERR_RPT_HOLD1 0x0F0 +#define NPU2_C_ERR_RPT_HOLD2 0x0F8 +#define NPU2_PERF_ADDR_MATCH 0x100 +#define NPU2_PERF_MATCH 0x108 +#define NPU2_PERF_MASK 0x110 +#define NPU2_DBG0_CFG 0x118 +#define NPU2_DBG1_CFG 0x120 +#define NPU2_C_ERR_RPT_MSG5 0x128 +#define NPU2_C_ERR_RPT_MSG6 0x130 + +/* CTL block registers */ +#define NPU2_CQ_CTL_MISC_CFG 0x000 +#define NPU2_CQ_CTL_MISC_CFG_CONFIG_OCAPI_MODE PPC_BIT(52) +#define NPU2_CQ_CTL_MISC_CFG_CONFIG_OTL0_ENABLE PPC_BIT(55) +#define NPU2_CQ_CTL_MISC_CFG_CONFIG_OTL1_ENABLE PPC_BIT(56) +#define NPU2_CQ_CTL_MISC_MMIOPA0_CONFIG 0x0B0 +#define NPU2_CQ_CTL_MISC_MMIOPA_ADDR PPC_BITMASK(1,35) +#define NPU2_CQ_CTL_MISC_MMIOPA_SIZE PPC_BITMASK(39,43) +#define NPU2_CQ_CTL_MISC_MMIOPA1_CONFIG 0x0B8 +#define NPU2_CQ_CTL_MISC_CFG1 0x008 +#define NPU2_CQ_FUTURE_CFG2 0x010 +#define NPU2_CQ_FUTURE_CFG3 0x018 +#define NPU2_CQ_PERF_MATCH 0x020 +#define NPU2_CQ_PERF_MASK 0x028 +#define NPU2_CQ_CTL_PMU_CNT 0x030 +#define NPU2_CQ_PERF_CFG 0x038 +#define NPU2_CQ_DBG0_CFG 0x040 +#define NPU2_CQ_DBG1_CFG 0x048 +#define NPU2_CQ_BRICK0_BDF2PE_MAP0 0x050 +#define NPU2_CQ_BRICK0_BDF2PE_MAP1 0x058 +#define NPU2_CQ_BRICK0_BDF2PE_MAP2 0x060 +#define NPU2_CQ_BRICK1_BDF2PE_MAP0 0x068 +#define NPU2_CQ_BRICK1_BDF2PE_MAP1 0x070 +#define NPU2_CQ_BRICK1_BDF2PE_MAP2 0x078 +#define NPU2_CQ_BRICK_BDF2PE_MAP_ENABLE PPC_BIT(0) +#define NPU2_CQ_BRICK_BDF2PE_MAP_WILDCARD PPC_BIT(1) +#define NPU2_CQ_BRICK_BDF2PE_MAP_PE PPC_BITMASK(4,7) +#define NPU2_CQ_BRICK_BDF2PE_MAP_BDF PPC_BITMASK(8,23) +#define NPU2_CQ_LPC_THRESHOLD_CFG 0x080 +#define NPU2_CQ_INHIBIT_CFG 0x088 +#define NPU2_CQ_CTL_STATUS 0x090 +#define NPU2_CQ_CTL_STATUS_BRK0_AM_FENCED PPC_BITMASK(48, 49) +#define NPU2_CQ_CTL_STATUS_BRK1_AM_FENCED PPC_BITMASK(50, 51) +#define NPU2_CQ_CTL_MISC_PA0_CONFIG 0x0A0 /* or should that be CS */ +#define NPU2_CQ_CTL_MISC_PA1_CONFIG 0x0A8 /* or should that be CS */ +#define NPU2_CQ_CTL_MISC_PA_CONFIG_MEMSELMATCH PPC_BITMASK(0,2) +#define NPU2_CQ_CTL_MISC_PA_CONFIG_GRANULE PPC_BIT(3) +#define NPU2_CQ_CTL_MISC_PA_CONFIG_SIZE PPC_BITMASK(4,7) +#define NPU2_CQ_CTL_MISC_PA_CONFIG_MODE PPC_BITMASK(8,11) +#define NPU2_CQ_CTL_MISC_PA_CONFIG_MASK PPC_BITMASK(13,19) +#define NPU2_CQ_C_ERR_RPT_MSG0 0x0C0 +#define NPU2_CQ_C_ERR_RPT_MSG1 0x0C8 +#define NPU2_CQ_C_ERR_RPT_FIRST0 0x0D0 +#define NPU2_CQ_C_ERR_RPT_FIRST1 0x0D8 +#define NPU2_CQ_C_ERR_RPT_MASK0 0x0E0 +#define NPU2_CQ_C_ERR_RPT_MASK1 0x0E8 +#define NPU2_CQ_C_ERR_RPT_HOLD0 0x0F0 +#define NPU2_CQ_C_ERR_RPT_HOLD1 0x0F8 +#define NPU2_CQ_CTL_CONFIG_ADDR0 0x120 +#define NPU2_CQ_CTL_CONFIG_ADDR1 0x128 +#define NPU2_CQ_CTL_CONFIG_ADDR_ENABLE PPC_BIT(0) +#define NPU2_CQ_CTL_CONFIG_ADDR_STATUS PPC_BITMASK(1, 3) +#define NPU2_CQ_CTL_CONFIG_ADDR_BUS_NUMBER PPC_BITMASK(4, 11) +#define NPU2_CQ_CTL_CONFIG_ADDR_DEVICE_NUMBER PPC_BITMASK(12, 16) +#define NPU2_CQ_CTL_CONFIG_ADDR_FUNCTION_NUMBER PPC_BITMASK(17, 19) +#define NPU2_CQ_CTL_CONFIG_ADDR_REGISTER_NUMBER PPC_BITMASK(20, 31) +#define NPU2_CQ_CTL_CONFIG_ADDR_TYPE PPC_BIT(32) +#define NPU2_CQ_CTL_FENCE_CONTROL_0 0x140 +#define NPU2_CQ_CTL_FENCE_CONTROL_1 0x148 +#define NPU2_CQ_CTL_FENCE_CONTROL_REQUEST_FENCE PPC_BITMASK(0, 1) + +/* DAT block registers */ +#define NPU2_CQ_DAT_MISC_CFG 0x008 +#define NPU2_CQ_DAT_MISC_CFG_CONFIG_OCAPI_MODE PPC_BIT(40) +#define NPU2_CQ_DAT_ECC_CFG 0x010 +#define NPU2_CQ_DAT_SCRATCH0 0x018 +#define NPU2_CQ_DAT_ECC_STATUS 0x020 +#define NPU2_CQ_DAT_ECC_MASK 0x028 +#define NPU2_CQ_DAT_ECC_FIRST 0x030 +#define NPU2_CQ_DAT_PARITY 0x038 +#define NPU2_CQ_DAT_PARITY_MASK 0x040 +#define NPU2_CQ_DAT_PARITY_FIRST 0x048 +#define NPU2_CQ_DAT_LOGIC 0x050 +#define NPU2_CQ_DAT_LOGIC_MASK 0x058 +#define NPU2_CQ_DAT_LOGIC_FIRST 0x060 +#define NPU2_CQ_DAT_RAS_MSG0 0x068 +#define NPU2_CQ_DAT_RAS_MSG1 0x070 +#define NPU2_CQ_DAT_DBG0_CFG 0x080 +#define NPU2_CQ_DAT_DBG1_CFG 0x088 +#define NPU2_CQ_DAT_SCRATCH1 0x0E0 +#define NPU2_CQ_DAT_BE_BUF_CTL 0x100 +#define NPU2_CQ_DAT_BE_BUF_WORD0 0x108 +#define NPU2_CQ_DAT_BE_BUF_WORD1 0x110 +#define NPU2_CQ_DAT_BE_BUF_STATUS 0x118 +#define NPU2_CQ_DAT_ERR_INJCT 0x130 +#define NPU2_CQ_DAT_ERR_RPT_INJCT 0x138 +#define NPU2_CQ_DAT_INHIBIT_CFG 0x140 + +/* NTL block registers */ +#define NPU2_NTL_MISC_CFG2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x000) +#define NPU2_NTL_MISC_CFG2_BRICK_ENABLE PPC_BIT(0) +#define NPU2_NTL_MISC_CFG2_NDL_RX_PARITY_ENA PPC_BIT(16) +#define NPU2_NTL_MISC_CFG2_NDL_TX_PARITY_ENA PPC_BIT(17) +#define NPU2_NTL_MISC_CFG2_NDL_PRI_PARITY_ENA PPC_BIT(18) +#define NPU2_NTL_MISC_CFG2_RCV_CREDIT_OVERFLOW_ENA PPC_BIT(19) +#define NPU2_NTL_MISC_CFG3(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x008) +#define NPU2_NTL_ERR_HOLD1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x010) +#define NPU2_NTL_ERR_MASK1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x018) +#define NPU2_NTL_ERR_FIRST1_OFF 0x020 +#define NPU2_NTL_ERR_FIRST1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x020) +#define NPU2_NTL_ERR_FIRST1_MASK(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x028) +#define NPU2_NTL_ERR_HOLD2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x030) +#define NPU2_NTL_ERR_MASK2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x038) +#define NPU2_NTL_ERR_FIRST2_OFF 0x040 +#define NPU2_NTL_ERR_FIRST2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x040) +#define NPU2_NTL_ERR_FIRST2_MASK(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x048) +#define NPU2_NTL_SCRATCH2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x050) +#define NPU2_NTL_SCRATCH(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x058) +#define NPU2_NTL_DBG0(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x060) +#define NPU2_NTL_DBG1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x068) +#define NPU2_NTL_PERF_CFG(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x070) +#define NPU2_NTL_PERF_CNT(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x078) +#define NPU2_NTL_CREQ_HDR(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x080) +#define NPU2_NTL_PRB_HDR(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x088) +#define NPU2_NTL_ATR_HDR(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x090) +#define NPU2_NTL_RSP_HDR(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x098) +#define NPU2_NTL_CRED_DATA(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x0A0) +#define NPU2_NTL_RSP_DATA(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x0A8) +#define NPU2_NTL_PRI_CFG(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x0B0) +#define NPU2_NTL_MISC_CFG1(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x0C0) +#define NPU2_NTL_SCRATCH1(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x0D0) +#define NPU2_NTL_LOW_POWER_CFG(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x0E0) +#define NPU2_NTL_DBG_INHIBIT_CFG(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x220) +#define NPU2_NTL_DISPLAY_CTL(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x280) +#define NPU2_NTL_DISPLAY_DATA0(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x288) +#define NPU2_NTL_DISPLAY_DATA1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x290) +#define NPU2_NTL_DISPLAY_DATA2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x298) +#define NPU2_NTL_RAS_ERR_MSG0(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x300) +#define NPU2_NTL_RAS_ERR_MSG1(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x308) +#define NPU2_NTL_RAS_ERR_MSG2(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x310) +#define NPU2_NTL_RAS_ERR_MSG3(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x318) +#define NPU2_NTL_ECC_ERR_INJCT(ndev) NPU2_NTL_REG_OFFSET(ndev, 0x340) +#define NPU2_NTL_CRED_HDR_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x400) +#define NPU2_NTL_PRB_HDR_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x410) +#define NPU2_NTL_ATR_HDR_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x418) +#define NPU2_NTL_RSP_HDR_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x428) +#define NPU2_NTL_CRED_DATA_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x430) +#define NPU2_NTL_RSP_DATA_CREDIT_TX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x438) +#define NPU2_NTL_CRED_HDR_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x440) +#define NPU2_NTL_DBD_HDR_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x448) +#define NPU2_NTL_ATSD_HDR_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x460) +#define NPU2_NTL_RSP_HDR_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x468) +#define NPU2_NTL_CRED_DATA_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x470) +#define NPU2_NTL_RSP_DATA_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x478) +#define NPU2_NTL_RB_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x480) +#define NPU2_NTL_WAB_CREDIT_RX(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x488) +#define NPU2_NTL_CQ_FENCE_STATUS(ndev) NPU2_NTLU_REG_OFFSET(ndev, 0x500) +#define NPU2_NTL_DL_CONTROL(ndev) NPU2_DL_REG_OFFSET(ndev, 0xFFF4) +#define NPU2_NTL_DL_CONFIG(ndev) NPU2_DL_REG_OFFSET(ndev, 0xFFF8) +#define NPU2_NTL_DL_CLK_CTRL(ndev) NPU2_DL_REG_OFFSET(ndev, 0x001C) + +/* OpenCAPI - XSL registers */ +#define NPU2_XSL_PSL_LLCMD_A0 0x008 +#define NPU2_XSL_PSL_SCNTL_A0 0x010 +#define NPU2_XSL_PSL_SCNTL_A0_MULTI_AFU_DIAL PPC_BIT(0) +#define NPU2_XSL_DEF 0x040 +#define NPU2_XSL_GP 0x058 +#define NPU2_XSL_GP_BLOOM_FILTER_ENABLE PPC_BIT(16) +#define NPU2_XSL_WRAP_CFG 0x0C0 +#define NPU2_XSL_WRAP_CFG_XSLO_CLOCK_ENABLE PPC_BIT(0) +#define NPU2_XSL_PSL_SPAP_A0 0 +#define NPU2_XSL_PSL_SPAP_A1 0x18 +#define NPU2_XSL_PSL_SPAP_EN PPC_BIT(63) + +/* OpenCAPI - OTL registers */ +#define NPU2_OTL_CONFIG0(stack, block) NPU2_REG_OFFSET(stack, block, 0x000) +#define NPU2_OTL_CONFIG0_EN PPC_BIT(0) +#define NPU2_OTL_CONFIG0_BLOCK_PE_HANDLE PPC_BIT(1) +#define NPU2_OTL_CONFIG0_BRICKID PPC_BITMASK(2, 3) +#define NPU2_OTL_CONFIG0_PE_MASK PPC_BITMASK(4, 7) +#define NPU2_OTL_CONFIG0_ERAT_HASH_0 PPC_BITMASK(8, 13) +#define NPU2_OTL_CONFIG0_ERAT_HASH_1 PPC_BITMASK(14, 19) +#define NPU2_OTL_CONFIG0_ERAT_HASH_2 PPC_BITMASK(20, 25) +#define NPU2_OTL_CONFIG0_ERAT_HASH_3 PPC_BITMASK(26, 31) +#define NPU2_OTL_CONFIG0_BLOCK_TID_OVERRIDE PPC_BIT(50) +#define NPU2_OTL_TLX_CREDITS(stack, block) NPU2_REG_OFFSET(stack, block, 0x050) +#define NPU2_OTL_TLX_CREDITS_VC0_CREDITS PPC_BITMASK(0, 7) +#define NPU2_OTL_TLX_CREDITS_VC3_CREDITS PPC_BITMASK(24, 31) +#define NPU2_OTL_TLX_CREDITS_DCP0_CREDITS PPC_BITMASK(32, 39) +#define NPU2_OTL_TLX_CREDITS_DCP1_CREDITS PPC_BITMASK(56, 63) +#define NPU2_OTL_VC_CREDITS(stack, block) NPU2_REG_OFFSET(stack, block, 0x090) +#define NPU2_OTL_CONFIG1(stack, block) NPU2_REG_OFFSET(stack, block, 0x058) +#define NPU2_OTL_CONFIG1_TX_TEMP1_EN PPC_BIT(1) +#define NPU2_OTL_CONFIG1_TX_TEMP2_EN PPC_BIT(2) +#define NPU2_OTL_CONFIG1_TX_TEMP3_EN PPC_BIT(3) +#define NPU2_OTL_CONFIG1_TX_DRDY_WAIT PPC_BITMASK(5, 7) +#define NPU2_OTL_CONFIG1_TX_TEMP0_RATE PPC_BITMASK(8, 11) +#define NPU2_OTL_CONFIG1_TX_TEMP1_RATE PPC_BITMASK(12, 15) +#define NPU2_OTL_CONFIG1_TX_TEMP2_RATE PPC_BITMASK(16, 19) +#define NPU2_OTL_CONFIG1_TX_TEMP3_RATE PPC_BITMASK(20, 23) +#define NPU2_OTL_CONFIG1_TX_CRET_FREQ PPC_BITMASK(32, 34) +#define NPU2_OTL_CONFIG1_TX_AGE_FREQ PPC_BITMASK(35, 39) +#define NPU2_OTL_CONFIG1_TX_RS2_HPWAIT PPC_BITMASK(40, 45) +#define NPU2_OTL_CONFIG1_TX_RQ4_HPWAIT PPC_BITMASK(46, 51) +#define NPU2_OTL_CONFIG1_TX_RQ6_HPWAIT PPC_BITMASK(52, 57) +#define NPU2_OTL_CONFIG1_TX_CBUF_ECC_DIS PPC_BIT(58) +#define NPU2_OTL_CONFIG1_TX_STOP_LINK PPC_BIT(59) +#define NPU2_OTL_CONFIG1_TX_STOP_ON_UE PPC_BIT(60) +#define NPU2_OTL_CONFIG1_TX_T0_MASK_CRTN0 PPC_BIT(61) +#define NPU2_OTL_CONFIG1_TX_T123_MASK_CRTN0 PPC_BIT(62) +#define NPU2_OTL_CONFIG2(stack, block) NPU2_REG_OFFSET(stack, block, 0x0C0) +#define NPU2_OTL_CONFIG2_TX_SEND_EN PPC_BIT(0) + +#define NPU2_OTL_OSL_DSISR(stack, block) NPU2_REG_OFFSET(stack, block, 0x000) +#define NPU2_OTL_OSL_DAR(stack, block) NPU2_REG_OFFSET(stack, block, 0x008) +#define NPU2_OTL_OSL_TFC(stack, block) NPU2_REG_OFFSET(stack, block, 0x010) +#define NPU2_OTL_OSL_PEHANDLE(stack, block) NPU2_REG_OFFSET(stack, block, 0x018) +#define NPU2_OTL_ERR_RPT_HOLD0 0x30 +#define NPU2_OTL_RAS_ERR_MSG0 0x68 +#define NPU2_OTL_RXI_ERR_SIG 0x70 +#define NPU2_OTL_RXO_ERR_SIG 0x78 +#define NPU2_OTL_ERR_RPT_HOLD1 0xB0 + + +/* Misc block registers. Unlike the SM/CTL/DAT/NTL registers above + * there is only a single instance of each of these in the NPU so we + * define them as absolute offsets. */ +#define NPU2_MISC_DBG_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x000) +#define NPU2_MISC_RELAXTED_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x008) +#define NPU2_MISC_LCO_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x010) +#define NPU2_MISC_OPTICAL_IO_CFG0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x018) +#define NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2 PPC_BITMASK(0, 2) +#define NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1 PPC_BITMASK(3, 4) +#define NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5 PPC_BITMASK(5, 6) +#define NPU2_MISC_ERR_RPT_HOLD NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x020) +#define NPU2_MISC_ERR_RPT_MASK NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x028) +#define NPU2_MISC_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x030) +#define NPU2_MISC_CFG_CONFIG_SYNC_WAIT PPC_BITMASK(0,4) +#define NPU2_MISC_CFG_PERF_CONFIG_ENABLE PPC_BIT(5) +#define NPU2_MISC_CFG_PERF_CONFIG_PE_MASK PPC_BIT(6) +#define NPU2_MISC_CFG_PERF_CONFIG_PE_MATCH PPC_BITMASK(7,10) +#define NPU2_MISC_CFG_IPI_PS PPC_BIT(11) +#define NPU2_MISC_CFG_IPI_PS_4K 0 +#define NPU2_MISC_CFG_IPI_PS_64K 1 +#define NPU2_MISC_CFG_IPI_OS PPC_BIT(12) +#define NPU2_MISC_CFG_IPI_OS_AIX 0 +#define NPU2_MISC_CFG_IPI_OS_LINUX 1 +#define NPU2_MISC_INHIBIT_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x038) +#define NPU2_MISC_FREEZE_ENABLE0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x040) +#define NPU2_MISC_FREEZE_ENABLE1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x048) +#define NPU2_MISC_FENCE_ENABLE0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x050) +#define NPU2_MISC_FENCE_ENABLE1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x058) +#define NPU2_MISC_IRQ_ENABLE0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x060) +#define NPU2_MISC_IRQ_ENABLE1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x068) +#define NPU2_MISC_NPU_VERSION NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x080) +#define NPU2_MISC_ERR_CTL_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x088) +#define NPU2_MISC_RING_ACK_ERR NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x090) +#define NPU2_MISC_IRQ_BASE NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x098) +#define NPU2_MISC_IRQ_BASE_MASK PPC_BITMASK(13, 51) +#define NPU2_MISC_ERR_BRICK_GROUP NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x0A0) +#define NPU2_MISC_FREEZE_STATE NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x0A8) +#define NPU2_MISC_FENCE_STATE NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x0B0) +#define NPU2_MISC_IRQ_REQUEST NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x0B8) +#define NPU2_MISC_BRICK0_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x100) +#define NPU2_MISC_BRICK0_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x108) +#define NPU2_MISC_BRICK0_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x110) +#define NPU2_MISC_BRICK1_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x118) +#define NPU2_MISC_BRICK1_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x120) +#define NPU2_MISC_BRICK1_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x128) +#define NPU2_MISC_BRICK2_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x130) +#define NPU2_MISC_BRICK2_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x138) +#define NPU2_MISC_BRICK2_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x140) +#define NPU2_MISC_BRICK3_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x148) +#define NPU2_MISC_BRICK3_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x150) +#define NPU2_MISC_BRICK3_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x158) +#define NPU2_MISC_BRICK4_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x160) +#define NPU2_MISC_BRICK4_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x168) +#define NPU2_MISC_BRICK4_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x170) +#define NPU2_MISC_BRICK5_BDF2PE_MAP0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x178) +#define NPU2_MISC_BRICK5_BDF2PE_MAP1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x180) +#define NPU2_MISC_BRICK5_BDF2PE_MAP2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x188) +#define NPU2_MISC_BRICK_BDF2PE_MAP_ENABLE PPC_BIT(0) +#define NPU2_MISC_BRICK_BDF2PE_MAP_PE PPC_BITMASK(4,7) +#define NPU2_MISC_BRICK_BDF2PE_MAP_BDF PPC_BITMASK(8,23) +#define NPU2_MISC_PESTB(pe) NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x200 + (pe)*8) +#define NPU2_MISC_IRQ_LOG0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x300) +#define NPU2_MISC_IRQ_LOG01 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x308) +#define NPU2_MISC_IRQ_LOG02 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x310) +#define NPU2_MISC_IRQ_LOG03 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x318) +#define NPU2_MISC_IRQ_LOG04 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x320) +#define NPU2_MISC_IRQ_LOG05 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x328) +#define NPU2_MISC_IRQ_LOG06 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x330) +#define NPU2_MISC_IRQ_LOG07 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x338) +#define NPU2_MISC_IRQ_LOG08 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x340) +#define NPU2_MISC_IRQ_LOG09 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x348) +#define NPU2_MISC_IRQ_LOG10 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x350) +#define NPU2_MISC_IRQ_LOG11 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x358) +#define NPU2_MISC_IRQ_LOG12 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x360) +#define NPU2_MISC_IRQ_LOG13 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x368) +#define NPU2_MISC_IRQ_LOG14 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x370) +#define NPU2_MISC_IRQ_LOG15 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x378) +#define NPU2_MISC_FENCE_ENABLE2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x400) +#define NPU2_MISC_IRQ_ENABLE2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, 0x408) + +/* Misc register, direct access only */ +#define NPU2_MISC_FIR0_MASK 0x2C03 +#define NPU2_MISC_FIR1_MASK 0x2C43 +#define NPU2_MISC_FIR2_MASK 0x2C83 + +/* ATS block registers */ +#define NPU2_ATS_PMU_CTL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x000) +#define NPU2_ATS_PMU_CNT NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x008) +#define NPU2_ATS_ERR_INJCT NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x010) +#define NPU2_ATS_DBG_CTL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x018) +#define NPU2_ATS_CHICKEN_SWITCH NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x020) +#define NPU2_ATS_ERR_RPT NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x028) +#define NPU2_ATS_ERR_RPT_MASK NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x030) +#define NPU2_ATS_CTL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x100) +#define NPU2_ATS_IODA_TBL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x108) +#define NPU2_ATS_IODA_TBL_TVT 9 +#define NPU2_ATS_IODA_TBL_TVT_TTA PPC_BITMASK(0,47) +#define NPU2_ATS_IODA_TBL_TVT_LEVEL PPC_BITMASK(48,50) +#define NPU2_ATS_IODA_TBL_TVT_SIZE PPC_BITMASK(51,55) +#define NPU2_ATS_IODA_TBL_TVT_PSIZE PPC_BITMASK(59,63) +#define NPU2_ATS_IODA_TBL_TCD 10 +#define NPU2_ATS_IODA_TBL_TDR 11 +#define NPU2_ATS_IODA_TBL_TDRMEM 12 +#define NPU2_ATS_IODA_TBL_XLTEA 16 +#define NPU2_ATS_IODA_TBL_AUTOINC PPC_BIT(0) +#define NPU2_ATS_IODA_TBL_SELECT PPC_BITMASK(11,15) +#define NPU2_ATS_IODA_TBL_INDEX PPC_BITMASK(54,63) +#define NPU2_ATS_IODA_DATA NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x110) +#define NPU2_ATS_DMA_SYNC NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x118) +#define NPU2_ATS_TCE_KILL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x120) +#define NPU2_ATS_TCE_KILL_ALL PPC_BIT(0) +#define NPU2_ATS_TCE_KILL_ONE PPC_BIT(2) +#define NPU2_ATS_TCE_KILL_PENUM PPC_BITMASK(4, 7) +#define NPU2_ATS_QUIESCE_DMA NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x128) +#define NPU2_ATS_TCE_TIMEOUT_CTL NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x130) +#define NPU2_ATS_ERR_STATUS NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x138) +#define NPU2_ATS_ERR_MASK NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x140) +#define NPU2_ATS_ERR_FIRST NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x148) +#define NPU2_ATS_ERR_FIRST_MASK NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_ATS, 0x150) + +/* XTS block registers */ +#define NPU2_XTS_ERR_RPT_STATUS NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x000) +#define NPU2_XTS_ERR_RPT_INJCT NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x008) +#define NPU2_XTS_ERR_MASK NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x010) +#define NPU2_XTS_ERR_FIRST NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x018) +#define NPU2_XTS_CFG NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x020) +#define NPU2_XTS_CFG_MMIOSD PPC_BIT(1) +#define NPU2_XTS_CFG_TRY_ATR_RO PPC_BIT(6) +#define NPU2_XTS_CFG_OPENCAPI PPC_BIT(15) +#define NPU2_XTS_CFG2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x028) +#define NPU2_XTS_CFG2_NO_FLUSH_ENA PPC_BIT(49) +#define NPU2_XTS_CFG2_XSL1_ENA PPC_BIT(54) +#define NPU2_XTS_CFG2_XSL2_ENA PPC_BIT(55) +#define NPU2_XTS_DBG_CFG0 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x030) +#define NPU2_XTS_DBG_CFG1 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x038) +#define NPU2_XTS_PMU_CNT NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x040) +#define NPU2_XTS_ATR_MISS NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x050) +#define NPU2_XTS_ATR_MISS_CLR NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x058) +#define NPU2_XTS_ATR_MISS2 NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x060) +#define NPU2_XTS_MMIO_ATSD0_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x100) +#define NPU2_XTS_MMIO_ATSD1_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x108) +#define NPU2_XTS_MMIO_ATSD2_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x110) +#define NPU2_XTS_MMIO_ATSD3_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x118) +#define NPU2_XTS_MMIO_ATSD4_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x120) +#define NPU2_XTS_MMIO_ATSD5_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x128) +#define NPU2_XTS_MMIO_ATSD6_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x130) +#define NPU2_XTS_MMIO_ATSD7_LPARID NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x138) +#define NPU2_XTS_MMIO_ATSD_MSR_HV PPC_BIT(51) +#define NPU2_XTS_MMIO_ATSD_LPARID PPC_BITMASK(52, 63) +#define NPU2_XTS_BDF_MAP NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x4000) +#define NPU2_XTS_BDF_MAP_VALID PPC_BIT(0) +#define NPU2_XTS_BDF_MAP_UNFILT PPC_BIT(1) +#define NPU2_XTS_BDF_MAP_STACK PPC_BITMASK(4, 6) +#define NPU2_XTS_BDF_MAP_BRICK PPC_BIT(7) +#define NPU2_XTS_BDF_MAP_BDF PPC_BITMASK(16, 31) +#define NPU2_XTS_BDF_MAP_XLAT PPC_BITMASK(39, 40) +#define NPU2_XTS_BDF_MAP_LPCR_ISL PPC_BIT(44) +#define NPU2_XTS_BDF_MAP_LPCR_TC PPC_BIT(45) +#define NPU2_XTS_BDF_MAP_LPARSHORT PPC_BITMASK(48, 51) +#define NPU2_XTS_BDF_MAP_LPARID PPC_BITMASK(52, 63) +#define NPU2_XTS_PID_MAP NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x8000) +#define NPU2_XTS_PID_MAP_VALID_ATRGPA0 PPC_BIT(0) +#define NPU2_XTS_PID_MAP_VALID_ATRGPA1 PPC_BIT(1) +#define NPU2_XTS_PID_MAP_VALID_ATSD PPC_BIT(2) +#define NPU2_XTS_PID_MAP_MSR PPC_BITMASK(25,31) +#define NPU2_XTS_PID_MAP_MSR_DR PPC_BIT(25) +#define NPU2_XTS_PID_MAP_MSR_TA PPC_BIT(26) +#define NPU2_XTS_PID_MAP_MSR_HV PPC_BIT(27) +#define NPU2_XTS_PID_MAP_MSR_PR PPC_BIT(28) +#define NPU2_XTS_PID_MAP_MSR_US PPC_BIT(29) +#define NPU2_XTS_PID_MAP_MSR_SF PPC_BIT(30) +#define NPU2_XTS_PID_MAP_MSR_UV PPC_BIT(31) +#define NPU2_XTS_PID_MAP_LPARSHORT PPC_BITMASK(40, 43) +#define NPU2_XTS_PID_MAP_PASID PPC_BITMASK(44, 63) +#define NPU2_XTS_SEIDR_MAP NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x8008) +#define NPU2_XTS_AMR_MAP NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_XTS, 0x8010) + +/* XTS ATSD block */ +#define NPU2_XTS_MMIO_ATSD_LAUNCH 0x000 +#define NPU2_XTS_MMIO_ATSD_AVA 0x008 +#define NPU2_XTS_MMIO_ATSD_STATUS 0x010 +#define MMIO_ATSD_ADDR(p, n) (u64) p + NPU2_REG_OFFSET(NPU2_STACK_ATSD,\ + NPU2_BLOCK_ATSD##n, NPU2_XTS_MMIO_ATSD_LAUNCH) + +/* ALTD SCOM addresses */ +#define NPU2_MISC_SCOM_IND_SCOM_ADDR 0x68e +#define NPU2_MISC_DA_ADDR PPC_BITMASK(0, 23) +#define NPU2_MISC_DA_LEN PPC_BITMASK(24, 25) +#define NPU2_MISC_DA_LEN_4B 2 +#define NPU2_MISC_DA_LEN_8B 3 +#define NPU2_MISC_SCOM_IND_SCOM_DATA 0x68f + +#define NPU2_FIR_OFFSET 0x40 +#define NPU2_FIR_MASK_OFFSET 0x3 +#define NPU2_FIR_ACTION0_OFFSET 0x6 +#define NPU2_FIR_ACTION1_OFFSET 0x7 + +#define NPU2_FIR_REGISTER_0 0x0000000005013C00 +#define NPU2_FIR_REGISTER_1 0x0000000005013C40 +#define NPU2_FIR_REGISTER_2 0x0000000005013C80 + +#define NPU2_TOTAL_FIR_REGISTERS 3 + +/* + * Can't use enums for 64 bit values, use #defines + */ +#define NPU2_CHECKSTOP_REG0_NTL_ARRAY_CE PPC_BIT(0) +#define NPU2_CHECKSTOP_REG0_NTL_ARRAY_HDR_CE PPC_BIT(1) +#define NPU2_CHECKSTOP_REG0_NTL_ARRAY_DATA_UE PPC_BIT(2) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_FLIT_PERR PPC_BIT(3) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_DATA_PERR PPC_BIT(4) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_PKT_MALFOR PPC_BIT(5) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_PKT_UNSUPPORTED PPC_BIT(6) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_CONFIG_ERR PPC_BIT(7) +#define NPU2_CHECKSTOP_REG0_NTL_NVL_CRC_ERR PPC_BIT(8) +#define NPU2_CHECKSTOP_REG0_NTL_PRI_ERR PPC_BIT(9) +#define NPU2_CHECKSTOP_REG0_NTL_LOGIC_ERR PPC_BIT(10) +#define NPU2_CHECKSTOP_REG0_NTL_LMD_POISON PPC_BIT(11) +#define NPU2_CHECKSTOP_REG0_NTL_ARRAY_DATA_SUE PPC_BIT(12) +#define NPU2_CHECKSTOP_REG0_CTL_ARRAY_CE PPC_BIT(13) +#define NPU2_CHECKSTOP_REG0_CTL_PBUS_RECOV_ERR PPC_BIT(14) +#define NPU2_CHECKSTOP_REG0_CTL_REG_RING_ERR PPC_BIT(15) +#define NPU2_CHECKSTOP_REG0_CTL_MMIO_ST_DATA_UE PPC_BIT(16) +#define NPU2_CHECKSTOP_REG0_CTL_PEF PPC_BIT(17) +#define NPU2_CHECKSTOP_REG0_CTL_NVL_CFG_ERR PPC_BIT(18) +#define NPU2_CHECKSTOP_REG0_CTL_NVL_FATAL_ERR PPC_BIT(19) +#define NPU2_CHECKSTOP_REG0_RESERVED_1 PPC_BIT(20) +#define NPU2_CHECKSTOP_REG0_CTL_ARRAY_UE PPC_BIT(21) +#define NPU2_CHECKSTOP_REG0_CTL_PBUS_PERR PPC_BIT(22) +#define NPU2_CHECKSTOP_REG0_CTL_PBUS_FATAL_ERR PPC_BIT(23) +#define NPU2_CHECKSTOP_REG0_CTL_PBUS_CONFIG_ERR PPC_BIT(24) +#define NPU2_CHECKSTOP_REG0_CTL_FWD_PROGRESS_ERR PPC_BIT(25) +#define NPU2_CHECKSTOP_REG0_CTL_LOGIC_ERR PPC_BIT(26) +#define NPU2_CHECKSTOP_REG0_DAT_DATA_BE_UE PPC_BIT(29) +#define NPU2_CHECKSTOP_REG0_DAT_DATA_BE_CE PPC_BIT(30) +#define NPU2_CHECKSTOP_REG0_DAT_DATA_BE_PERR PPC_BIT(31) +#define NPU2_CHECKSTOP_REG0_DAT_CREG_PERR PPC_BIT(32) +#define NPU2_CHECKSTOP_REG0_DAT_RTAG_PERR PPC_BIT(33) +#define NPU2_CHECKSTOP_REG0_DAT_STATE_PERR PPC_BIT(34) +#define NPU2_CHECKSTOP_REG0_DAT_LOGIC_ERR PPC_BIT(35) +#define NPU2_CHECKSTOP_REG0_DAT_DATA_BE_SUE PPC_BIT(36) +#define NPU2_CHECKSTOP_REG0_DAT_PBRX_SUE PPC_BIT(37) +#define NPU2_CHECKSTOP_REG0_XTS_INT PPC_BIT(40) +#define NPU2_CHECKSTOP_REG0_XTS_SRAM_CE PPC_BIT(41) +#define NPU2_CHECKSTOP_REG0_XTS_SRAM_UE PPC_BIT(42) +#define NPU2_CHECKSTOP_REG0_XTS_PROTOCOL_CE PPC_BIT(43) +#define NPU2_CHECKSTOP_REG0_XTS_PROTOCOL_UE PPC_BIT(44) +#define NPU2_CHECKSTOP_REG0_XTS_PBUS_PROTOCOL PPC_BIT(45) + +#define NPU2_CHECKSTOP_REG1_NDL_BRK0_STALL PPC_BIT(0) +#define NPU2_CHECKSTOP_REG1_NDL_BRK0_NOSTALL PPC_BIT(1) +#define NPU2_CHECKSTOP_REG1_NDL_BRK1_STALL PPC_BIT(2) +#define NPU2_CHECKSTOP_REG1_NDL_BRK1_NOSTALL PPC_BIT(3) +#define NPU2_CHECKSTOP_REG1_NDL_BRK2_STALL PPC_BIT(4) +#define NPU2_CHECKSTOP_REG1_NDL_BRK2_NOSTALL PPC_BIT(5) +#define NPU2_CHECKSTOP_REG1_NDL_BRK3_STALL PPC_BIT(6) +#define NPU2_CHECKSTOP_REG1_NDL_BRK3_NOSTALL PPC_BIT(7) +#define NPU2_CHECKSTOP_REG1_NDL_BRK4_STALL PPC_BIT(8) +#define NPU2_CHECKSTOP_REG1_NDL_BRK4_NOSTALL PPC_BIT(9) +#define NPU2_CHECKSTOP_REG1_NDL_BRK5_STALL PPC_BIT(10) +#define NPU2_CHECKSTOP_REG1_NDL_BRK5_NOSTALL PPC_BIT(11) +#define NPU2_CHECKSTOP_REG1_MISC_REG_RING_ERR PPC_BIT(12) +#define NPU2_CHECKSTOP_REG1_MISC_INT_RA_PERR PPC_BIT(13) +#define NPU2_CHECKSTOP_REG1_MISC_DA_ADDR_PERR PPC_BIT(14) +#define NPU2_CHECKSTOP_REG1_MISC_CTRL_PERR PPC_BIT(15) +#define NPU2_CHECKSTOP_REG1_MISC_NMMU_ERR PPC_BIT(16) +#define NPU2_CHECKSTOP_REG1_ATS_TVT_ENTRY_INVALID PPC_BIT(17) +#define NPU2_CHECKSTOP_REG1_ATS_TVT_ADDR_RANGE_ERR PPC_BIT(18) +#define NPU2_CHECKSTOP_REG1_ATS_TCE_PAGE_ACCESS_CA_ERR PPC_BIT(19) +#define NPU2_CHECKSTOP_REG1_ATS_TCE_CACHE_MULT_HIT_ERR PPC_BIT(20) +#define NPU2_CHECKSTOP_REG1_ATS_TCE_PAGE_ACCESS_TW_ERR PPC_BIT(21) +#define NPU2_CHECKSTOP_REG1_ATS_TCE_REQ_TO_ERR PPC_BIT(22) +#define NPU2_CHECKSTOP_REG1_ATS_TCD_PERR PPC_BIT(23) +#define NPU2_CHECKSTOP_REG1_ATS_TDR_PERR PPC_BIT(24) +#define NPU2_CHECKSTOP_REG1_ATS_AT_EA_UE PPC_BIT(25) +#define NPU2_CHECKSTOP_REG1_ATS_AT_EA_CE PPC_BIT(26) +#define NPU2_CHECKSTOP_REG1_ATS_AT_TDRMEM_UE PPC_BIT(27) +#define NPU2_CHECKSTOP_REG1_ATS_AT_TDRMEM_CE PPC_BIT(28) +#define NPU2_CHECKSTOP_REG1_ATS_AT_RSPOUT_UE PPC_BIT(29) +#define NPU2_CHECKSTOP_REG1_ATS_AT_RSPOUT_CE PPC_BIT(30) +#define NPU2_CHECKSTOP_REG1_ATS_TVT_PERR PPC_BIT(31) +#define NPU2_CHECKSTOP_REG1_ATS_IODA_ADDR_PERR PPC_BIT(32) +#define NPU2_CHECKSTOP_REG1_ATS_NPU_CTRL_PERR PPC_BIT(33) +#define NPU2_CHECKSTOP_REG1_ATS_NPU_TOR_PERR PPC_BIT(34) +#define NPU2_CHECKSTOP_REG1_ATS_INVAL_IODA_TBL_SEL PPC_BIT(35) + +#define NPU2_CHECKSTOP_REG2_XSL_MMIO_INVALIDATE_REQ_WHILE_1_INPROG PPC_BIT(36) +#define NPU2_CHECKSTOP_REG2_XSL_UNEXPECTED_ITAG_PORT_0 PPC_BIT(37) +#define NPU2_CHECKSTOP_REG2_XSL_UNEXPECTED_ITAG_PORT_1 PPC_BIT(38) +#define NPU2_CHECKSTOP_REG2_XSL_UNEXPECTED_RD_PEE_COMPLETION PPC_BIT(39) +#define NPU2_CHECKSTOP_REG2_XSL_UNEXPECTED_CO_RESP PPC_BIT(40) +#define NPU2_CHECKSTOP_REG2_XSL_XLAT_REQ_WHILE_SPAP_INVALID PPC_BIT(41) +#define NPU2_CHECKSTOP_REG2_XSL_INVALID_PEE PPC_BIT(42) +#define NPU2_CHECKSTOP_REG2_XSL_BLOOM_FILTER_PROTECT_ERR PPC_BIT(43) +#define NPU2_CHECKSTOP_REG2_XSL_CE PPC_BIT(46) +#define NPU2_CHECKSTOP_REG2_XSL_UE PPC_BIT(47) +#define NPU2_CHECKSTOP_REG2_XSL_SLBI_TLBI_BUFF_OVERFLOW PPC_BIT(48) +#define NPU2_CHECKSTOP_REG2_XSL_SBE_CORR_ERR_PB_CHKOUT_RSP_DATA PPC_BIT(49) +#define NPU2_CHECKSTOP_REG2_XSL_UE_PB_CHKOUT_RSP_DATA PPC_BIT(50) +#define NPU2_CHECKSTOP_REG2_XSL_SUE_PB_CHKOUT_RSP_DATA PPC_BIT(51) + +/* OpenCAPI - PowerBus and OBus configuration SCOM addresses */ +#define PU_IOE_PB_MISC_CFG 0x5013823 +#define PU_IOE_PB_MISC_CFG_SEL_03_NPU_NOT_PB PPC_BIT(13) +#define PU_IOE_PB_MISC_CFG_SEL_04_NPU_NOT_PB PPC_BIT(14) +#define PU_IOE_PB_MISC_CFG_SEL_05_NPU_NOT_PB PPC_BIT(15) +#define OBUS_LL0_IOOL_PHY_CONFIG 0x901080C +#define OBUS_LL3_IOOL_PHY_CONFIG 0xC01080C +#define OBUS_IOOL_PHY_CONFIG_ODL0_ENABLED PPC_BIT(52) +#define OBUS_IOOL_PHY_CONFIG_ODL1_ENABLED PPC_BIT(53) +#define OBUS_IOOL_PHY_CONFIG_ODL_PHY_SWAP PPC_BIT(54) +#define OBUS_IOOL_PHY_CONFIG_LINK0_OLL_ENABLED PPC_BIT(58) +#define OBUS_IOOL_PHY_CONFIG_LINK1_OLL_ENABLED PPC_BIT(59) +#define OBUS_IOOL_PHY_CONFIG_NV0_NPU_ENABLED PPC_BIT(61) +#define OBUS_IOOL_PHY_CONFIG_NV1_NPU_ENABLED PPC_BIT(62) +#define OBUS_IOOL_PHY_CONFIG_NV2_NPU_ENABLED PPC_BIT(63) +#define PU_IOE_PB_FP01_CFG 0x501380A +#define PU_IOE_PB_FP23_CFG 0x501380B +#define PU_IOE_PB_FP45_CFG 0x501380C +#define PU_IOE_PB_FP67_CFG 0x501380D +#define PU_IOE_PB_FP_CFG_FP0_FMR_DISABLE PPC_BIT(20) +#define PU_IOE_PB_FP_CFG_FP0_PRS_DISABLE PPC_BIT(25) +#define PU_IOE_PB_FP_CFG_FP1_FMR_DISABLE PPC_BIT(52) +#define PU_IOE_PB_FP_CFG_FP1_PRS_DISABLE PPC_BIT(57) + +#define OB_DLL_PERF_MONITOR_CONFIG(brick_index) \ + (0x901081C + ((brick_index - 2) >> 1) * 0x3000000) +#define OB_DLL_PERF_MONITOR_CONFIG_ENABLE PPC_BITMASK(0, 1) +#define OB_DLL_PERF_MONITOR_CONFIG_LINK0 0b10 +#define OB_DLL_PERF_MONITOR_CONFIG_LINK1 0b01 +#define OB_DLL_PERF_MONITOR_CONFIG_SIZE PPC_BITMASK(16, 23) +#define OB_DLL_PERF_MONITOR_CONFIG_SIZE16 0xFF +#define OB_DLL_PERF_MONITOR_SELECT(brick_index) \ + (0x901081D + ((brick_index - 2) >> 1) * 0x3000000) +#define OB_DLL_PERF_MONITOR_SELECT_COUNTER PPC_BITMASK(0, 7) +#define OB_DLL_PERF_MONITOR_SELECT_CRC_ODL 0x44 +#define OB_DLL_PERF_MONITOR_SELECT_CRC_DLX 0x45 +#define OB_DLL_PERF_COUNTER0(brick_index) \ + (0x901081E + ((brick_index - 2) >> 1) * 0x3000000) +#define OB_DLL_PERF_COUNTER0_VAL PPC_BITMASK(0, 31) + + +#define OB_ODL_OFFSET(brick_index) \ + ((((brick_index - 2) >> 1) * 0x3000000) + ((brick_index == 3 || brick_index == 4) ? 1 : 0)) + +#define OB_ODL_CONFIG(brick_index) \ + (0x901082A + OB_ODL_OFFSET(brick_index)) +#define OB_ODL_CONFIG_RESET PPC_BIT(0) +#define OB_ODL_CONFIG_VERSION PPC_BITMASK(2, 7) +#define OB_ODL_CONFIG_TRAIN_MODE PPC_BITMASK(8, 11) +#define OB_ODL_CONFIG_SUPPORTED_MODES PPC_BITMASK(12, 15) +#define OB_ODL_CONFIG_X4_BACKOFF_ENABLE PPC_BIT(16) +#define OB_ODL_CONFIG_PHY_CNTR_LIMIT PPC_BITMASK(20, 23) +#define OB_ODL_CONFIG_DEBUG_ENABLE PPC_BIT(33) +#define OB_ODL_CONFIG_FWD_PROGRESS_TIMER PPC_BITMASK(40, 43) +#define OB_ODL_STATUS(brick_index) \ + (0x901082C + OB_ODL_OFFSET(brick_index)) +#define OB_ODL_STATUS_TRAINED_MODE PPC_BITMASK(0,3) +#define OB_ODL_STATUS_RX_TRAINED_LANES PPC_BITMASK(16, 23) +#define OB_ODL_STATUS_TX_TRAINED_LANES PPC_BITMASK(24, 31) +#define OB_ODL_STATUS_TRAINING_STATE_MACHINE PPC_BITMASK(49, 51) +#define OB_ODL_TRAINING_STATUS(brick_index) \ + (0x901082E + OB_ODL_OFFSET(brick_index)) +#define OB_ODL_TRAINING_STATUS_STS_RX_PATTERN_B PPC_BITMASK(8, 15) +#define OB_ODL_ENDPOINT_INFO(brick_index) \ + (0x9010832 + OB_ODL_OFFSET(brick_index)) + +/* Config registers for NPU2 */ +#define NPU_STCK0_CS_SM0_MISC_CONFIG0 0x5011000 +#define NPU_STCK0_CS_SM1_MISC_CONFIG0 0x5011030 +#define NPU_STCK0_CS_SM2_MISC_CONFIG0 0x5011060 +#define NPU_STCK0_CS_SM3_MISC_CONFIG0 0x5011090 +#define NPU_STCK1_CS_SM0_MISC_CONFIG0 0x5011200 +#define NPU_STCK1_CS_SM1_MISC_CONFIG0 0x5011230 +#define NPU_STCK1_CS_SM2_MISC_CONFIG0 0x5011260 +#define NPU_STCK1_CS_SM3_MISC_CONFIG0 0x5011290 +#define NPU_STCK2_CS_SM0_MISC_CONFIG0 0x5011400 +#define NPU_STCK2_CS_SM1_MISC_CONFIG0 0x5011430 +#define NPU_STCK2_CS_SM2_MISC_CONFIG0 0x5011460 +#define NPU_STCK2_CS_SM3_MISC_CONFIG0 0x5011490 + +#endif /* __NPU2_REGS_H */ diff --git a/roms/skiboot/include/npu2.h b/roms/skiboot/include/npu2.h new file mode 100644 index 000000000..eb7c45587 --- /dev/null +++ b/roms/skiboot/include/npu2.h @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __NPU2_H +#define __NPU2_H + +#include <pci.h> +#include <phys-map.h> +#include <npu2-regs.h> + +/* Debugging options */ +#define NPU2DBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \ + (p)->phb_nvlink.opal_id, ##a) +#define NPU2INF(p, fmt, a...) prlog(PR_INFO, "NPU%d: " fmt, \ + (p)->phb_nvlink.opal_id, ##a) +#define NPU2ERR(p, fmt, a...) prlog(PR_ERR, "NPU%d: " fmt, \ + (p)->phb_nvlink.opal_id, ##a) + +#define NPU2DEVLOG(l, p, fmt, a...) prlog(l, "NPU%d:%d:%d.%d " fmt, \ + (p)->npu->phb_nvlink.opal_id, \ + PCI_BUS_NUM((p)->bdfn), \ + PCI_DEV((p)->bdfn), \ + PCI_FUNC((p)->bdfn), ##a) +#define NPU2DEVDBG(p, fmt, a...) NPU2DEVLOG(PR_DEBUG, p, fmt, ##a) +#define NPU2DEVINF(p, fmt, a...) NPU2DEVLOG(PR_INFO, p, fmt, ##a) +#define NPU2DEVERR(p, fmt, a...) NPU2DEVLOG(PR_ERR, p, fmt, ##a) + +#define OCAPIDBG(dev, fmt, a...) prlog(PR_DEBUG, "OCAPI[%d:%d]: " fmt, \ + dev->npu->chip_id, dev->brick_index, ## a) +#define OCAPIINF(dev, fmt, a...) prlog(PR_INFO, "OCAPI[%d:%d]: " fmt, \ + dev->npu->chip_id, dev->brick_index, ## a) +#define OCAPIERR(dev, fmt, a...) prlog(PR_ERR, "OCAPI[%d:%d]: " fmt, \ + dev->npu->chip_id, dev->brick_index, ## a) + + +/* + * Number of PEs supported + * + * The NPU supports PE numbers from 0-15. At present, we only assign a maximum + * of 1 PE per brick. + * + * NVLink devices are currently exposed to Linux underneath a single virtual + * PHB. Therefore, we give NVLink half the available PEs, which is enough for + * 6 bricks plus 1 reserved PE. + * + * For OpenCAPI, the BDF-to-PE registers are used exclusively for mapping + * bricks to System Interrupt Log registers (the BDF component of those + * registers is ignored). Currently, we allocate a fixed PE based on the brick + * index in the upper half of the PE namespace. + */ +#define NPU2_MAX_PE_NUM 8 +#define NPU2_RESERVED_PE_NUM 7 +#define NPU2_OCAPI_PE(ndev) ((ndev)->brick_index + NPU2_MAX_PE_NUM) + +#define NPU2_LINKS_PER_CHIP 6 + +/* Link flags */ +#define NPU2_DEV_PCI_LINKED 0x1 +#define NPU2_DEV_DL_RESET 0x2 + +/* Return the stack (0-2) of a device */ +#define NPU2DEV_STACK(ndev) ((ndev)->brick_index / 2) + +/* Return the brick number (0-1) within a stack */ +#define NPU2DEV_BRICK(ndev) ((ndev)->brick_index % 2) + +/* This represents the state of the actual hardware BARs not the + * emulated PCIe BARs. The is a subtle difference between the two as + * not all BARs are exposed outside of skiboot. */ +struct npu2_bar { + enum phys_map_type type; + int index; +#define NPU2_BAR_FLAG_ENABLED 0x0010 + +/* Generation ID's are a single space in the hardware but we split + * them in two for the emulated PCIe devices so we need to keep track + * of which one has been enabled/disabled. */ +#define NPU2_BAR_FLAG_ENABLED0 0x0080 +#define NPU2_BAR_FLAG_ENABLED1 0x0100 + uint32_t flags; + uint64_t base; + uint64_t size; + uint64_t reg; +}; + +/* Rpresents a BAR that is exposed via the PCIe emulated + * devices */ +struct npu2_pcie_bar { +#define NPU2_PCIE_BAR_FLAG_SIZE_HI 0x0020 +#define NPU2_PCIE_BAR_FLAG_TRAPPED 0x0040 + uint32_t flags; + struct npu2_bar npu2_bar; +}; + +enum npu2_dev_type { + NPU2_DEV_TYPE_UNKNOWN, + NPU2_DEV_TYPE_NVLINK, + NPU2_DEV_TYPE_OPENCAPI, +}; + +struct npu2; + +struct npu2_dev_nvlink { + /* For NVLink, device and function numbers are allocated based + * on GPU association. Links to connected to the same GPU will + * be exposed as different functions of the same + * bus/device. */ + uint32_t gpu_bdfn; + + /* PCI virtual device and the associated GPU device */ + struct pci_virt_device *pvd; + struct phb *phb; + struct pci_device *pd; + + uint8_t link_flags; + + /* Used to associate the NPU device with GPU PCI devices */ + const char *slot_label; +}; + +#define NPU2_DEV_BROKEN 0x1 + +struct npu2_dev { + enum npu2_dev_type type; + uint32_t link_index; + uint32_t brick_index; + uint64_t pl_xscom_base; + struct dt_node *dt_node; + struct npu2_pcie_bar bars[2]; + struct npu2 *npu; + long flags; + + uint32_t bdfn; + + /* Which PHY lanes this device is associated with */ + uint32_t lane_mask; + uint64_t link_speed; /* not used for NVLink */ + + /* Track currently running procedure and step number */ + uint16_t procedure_number; + uint16_t procedure_step; + unsigned long procedure_tb; + uint32_t procedure_status; + + /* NVLink */ + struct npu2_dev_nvlink nvlink; + + /* OpenCAPI */ + struct phb phb_ocapi; + uint64_t linux_pe; + unsigned long train_start; + unsigned long train_timeout; + uint64_t lpc_mem_base; + uint64_t lpc_mem_size; +}; + +struct npu2 { + uint32_t index; + struct dt_node *dt_node; + uint32_t chip_id; + uint64_t xscom_base; + void *regs; + uint64_t mm_base; + uint64_t mm_size; + uint32_t base_lsi; + uint32_t total_devices; + struct npu2_dev *devices; + enum phys_map_type gpu_map_type; + int ctx_ref[NPU2_XTS_BDF_MAP_SIZE]; + + /* IODA cache */ + uint64_t tve_cache[16]; + bool tx_zcal_complete[2]; + + /* + * Used to protect global MMIO space, in particular the XTS + * tables, and LPC allocation + */ + struct lock lock; + + /* NVLink */ + struct phb phb_nvlink; + + /* OCAPI */ + uint64_t i2c_port_id_ocapi; + struct lock i2c_lock; + uint8_t i2c_pin_mode; + uint8_t i2c_pin_wr_state; +}; + +static inline struct npu2 *phb_to_npu2_nvlink(struct phb *phb) +{ + assert(phb->phb_type == phb_type_npu_v2); + return container_of(phb, struct npu2, phb_nvlink); +} + +static inline struct npu2_dev *phb_to_npu2_dev_ocapi(struct phb *phb) +{ + assert(phb->phb_type == phb_type_npu_v2_opencapi); + return container_of(phb, struct npu2_dev, phb_ocapi); +} + +static inline struct phb *npu2_dev_to_phb(struct npu2_dev *ndev) +{ + switch (ndev->type) { + case NPU2_DEV_TYPE_NVLINK: + return &ndev->npu->phb_nvlink; + case NPU2_DEV_TYPE_OPENCAPI: + return &ndev->phb_ocapi; + default: + assert(false); + } +} + +void npu2_i2c_presence_detect(struct npu2 *npu); +int npu2_opencapi_init_npu(struct npu2 *npu); +int npu2_nvlink_init_npu(struct npu2 *npu); +void npu2_nvlink_create_phb(struct npu2 *npu, struct dt_node *dn); + +void npu2_write_4b(struct npu2 *p, uint64_t reg, uint32_t val); +uint32_t npu2_read_4b(struct npu2 *p, uint64_t reg); +void npu2_write(struct npu2 *p, uint64_t reg, uint64_t val); +uint64_t npu2_read(struct npu2 *p, uint64_t reg); +void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask); +void npu2_write_mask_4b(struct npu2 *p, uint64_t reg, uint32_t val, uint32_t mask); +int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, + uint32_t offset, uint32_t len, uint32_t *data, + bool write); +void npu2_dev_procedure_reset(struct npu2_dev *dev); + +void npu2_set_link_flag(struct npu2_dev *ndev, uint8_t flag); +void npu2_clear_link_flag(struct npu2_dev *ndev, uint8_t flag); +uint32_t reset_ntl(struct npu2_dev *ndev); +extern int nv_zcal_nominal; +void npu2_opencapi_phy_init(struct npu2_dev *dev); +int npu2_opencapi_phy_reset(struct npu2_dev *dev); +void npu2_opencapi_phy_prbs31(struct npu2_dev *dev); +void npu2_opencapi_bump_ui_lane(struct npu2_dev *dev); +int64_t npu2_freeze_status(struct phb *phb __unused, + uint64_t pe_number __unused, + uint8_t *freeze_state, + uint16_t *pci_error_type __unused, + uint16_t *severity __unused); +void npu2_dump_scoms(int chip_id); + +int64_t npu2_init_context(struct phb *phb, uint64_t msr, uint64_t bdf); +int64_t npu2_destroy_context(struct phb *phb, uint64_t bdf); +int64_t npu2_map_lpar(struct phb *phb, uint64_t bdf, uint64_t lparid, + uint64_t lpcr); +int64_t npu2_set_relaxed_order(struct phb *phb, uint32_t gcid, int pec, + bool enable); + +void npu2_opencapi_set_broken(struct npu2 *npu, int brick); + +#define NPU2_PHB_INDEX_BASE 7 +/* to avoid conflicts with PCI and for historical reasons */ + +static inline int npu2_get_phb_index(unsigned int brick_index) +{ + /* + * There's one virtual PHB per brick with opencapi, so we no + * longer have a 1-to-1 mapping between a NPU and a virtual + * PHB. And we want a static phb-index, as it is needed to use + * a slot table on some platforms. So we associate a per-chip + * phb-index based on the brick index. + * + * nvlink only creates one virtual PHB per chip, so it is + * treated as if using brick 0, which is never used by + * opencapi. + */ + return NPU2_PHB_INDEX_BASE + brick_index; +} + +#endif /* __NPU2_H */ diff --git a/roms/skiboot/include/npu3-regs.h b/roms/skiboot/include/npu3-regs.h new file mode 100644 index 000000000..380fb5491 --- /dev/null +++ b/roms/skiboot/include/npu3-regs.h @@ -0,0 +1,253 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NPU3_REGS_H +#define __NPU3_REGS_H + +#define NPU3_FIR(n) (0x2c00 + (n) * 0x40) +#define NPU3_FIR_MASK(n) (0x2c03 + (n) * 0x40) +#define NPU3_FIR_ACTION0(n) (0x2c06 + (n) * 0x40) +#define NPU3_FIR_ACTION1(n) (0x2c07 + (n) * 0x40) +#define NPU3_FIR_MAX 3 + +/* NPU RING: Indirect address/data port */ +#define NPU3_MISC_SCOM_IND_SCOM_ADDR 0x33e +#define NPU3_MISC_DA_ADDR PPC_BITMASK(0, 23) +#define NPU3_MISC_DA_LEN PPC_BITMASK(24, 25) +#define NPU3_MISC_DA_LEN_4B 2 +#define NPU3_MISC_DA_LEN_8B 3 +#define NPU3_MISC_SCOM_IND_SCOM_DATA 0x33f + +/* NPU RING: Indirect register blocks */ +#define NPU3_BLOCK(nib0, nib1) ((nib0) << 20 | (nib1) << 16) +#define NPU3_REG_BLOCK(reg) ((reg) & 0xff0000) +#define NPU3_REG_OFFSET(reg) ((reg) & 0xffff) + +#define NPU3_BLOCK_NDL_U(brk) NPU3_BLOCK(0 + (brk) / 2,\ + 8 + (brk) % 2 * 2) +#define NPU3_BLOCK_NTL_U(brk) NPU3_BLOCK(0 + (brk) / 2,\ + 9 + (brk) % 2 * 2) +#define NPU3_BLOCK_CQ_SM(n) NPU3_BLOCK(4, (n)) +#define NPU3_BLOCK_CQ_CTL NPU3_BLOCK(4, 4) +#define NPU3_BLOCK_CQ_DAT NPU3_BLOCK(4, 5) +#define NPU3_BLOCK_NDL(brk) NPU3_BLOCK(4 + (brk) / 2,\ + 8 + (brk) % 2 * 2) +#define NPU3_BLOCK_NTL(brk) NPU3_BLOCK(4 + (brk) / 2,\ + 9 + (brk) % 2 * 2) +#define NPU3_BLOCK_NPU_ATS NPU3_BLOCK(7, 0) +#define NPU3_BLOCK_NPU_XTS NPU3_BLOCK(7, 1) +#define NPU3_BLOCK_NPU_MISC NPU3_BLOCK(7, 2) +#define NPU3_BLOCK_NPU_XTS_ATSD(n) NPU3_BLOCK(8, (n)) + +/* NDL_U block registers */ +#define NPU3_DLPL_CTL(brk) (NPU3_BLOCK_NDL_U(brk) + 0xfff4) +#define NPU3_DLPL_CTL_RESET_RX PPC_BIT32(0) +#define NPU3_DLPL_CTL_RESET_MISC PPC_BIT32(1) +#define NPU3_DLPL_CFG(brk) (NPU3_BLOCK_NDL_U(brk) + 0xfff8) +#define NPU3_DLPL_CFG_PRI_BYTESWAP PPC_BIT32(0) + +/* NTL_U block registers */ +#define NPU3_NTL_MISC_CFG1(brk) (NPU3_BLOCK_NTL_U(brk) + 0x0c0) +#define NPU3_NTL_MISC_CFG1_NTL_RESET PPC_BITMASK(8, 9) +#define NPU3_NTL_CREQ_HDR_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x400) +#define NPU3_NTL_PRB_HDR_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x410) +#define NPU3_NTL_ATR_HDR_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x418) +#define NPU3_NTL_RSP_HDR_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x428) +#define NPU3_NTL_CREQ_DAT_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x430) +#define NPU3_NTL_RSP_DAT_CRED_SND(brk) (NPU3_BLOCK_NTL_U(brk) + 0x438) +#define NPU3_NTL_CREQ_HDR_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x440) +#define NPU3_NTL_DGD_HDR_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x448) +#define NPU3_NTL_ATSD_HDR_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x460) +#define NPU3_NTL_RSP_HDR_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x468) +#define NPU3_NTL_CREQ_DAT_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x470) +#define NPU3_NTL_RSP_DAT_CRED_RCV(brk) (NPU3_BLOCK_NTL_U(brk) + 0x478) +#define NPU3_NTL_CQ_FENCE_STATUS(brk) (NPU3_BLOCK_NTL_U(brk) + 0x500) +#define NPU3_NTL_CQ_FENCE_STATUS_FIELD PPC_BITMASK(0, 1) +#define NPU3_NTL_CQ_FENCE_STATUS_FULL 3 +#define NPU3_NTL_CQ_FENCE_STATUS_HALF 2 +#define NPU3_NTL_CQ_FENCE_STATUS_NONE 0 + +/* + * CQ_SM block registers + * + * Definitions here use NPU3_BLOCK_CQ_SM(0), but when npu3_write() is given + * one of these, it will do corresponding writes to every CQ_SM block. + */ +#define NPU3_MCP_MISC_CFG0 (NPU3_BLOCK_CQ_SM(0) + 0x000) +#define NPU3_MCP_MISC_CFG0_ENABLE_PBUS PPC_BIT(26) +#define NPU3_MCP_MISC_CFG0_ENABLE_SNARF_CPM PPC_BIT(27) +#define NPU3_MCP_MISC_CFG0_OCAPI_MODE PPC_BITMASK(44, 48) +#define NPU3_MCP_MISC_CFG0_NVLINK_MODE PPC_BITMASK(49, 53) +#define NPU3_MCP_MISC_CFG1 (NPU3_BLOCK_CQ_SM(0) + 0x008) +#define NPU3_MCP_MISC_CFG2 (NPU3_BLOCK_CQ_SM(0) + 0x0f0) +#define NPU3_SNP_MISC_CFG0 (NPU3_BLOCK_CQ_SM(0) + 0x180) +#define NPU3_SNP_MISC_CFG0_ENABLE_PBUS PPC_BIT(2) +#define NPU3_SNP_MISC_CFG0_OCAPI_MODE PPC_BITMASK(32, 36) +#define NPU3_SNP_MISC_CFG0_NVLINK_MODE PPC_BITMASK(37, 41) +#define NPU3_GPU_MEM_BAR(brk) (NPU3_BLOCK_CQ_SM(0) + 0x190 + (brk) * 8) +#define NPU3_GPU_MEM_BAR_ENABLE PPC_BIT(0) +#define NPU3_GPU_MEM_BAR_ADDR_MASK PPC_BITMASK(1, 35) +#define NPU3_GPU_MEM_BAR_ADDR PPC_BITMASK(1, 21) +#define NPU3_GPU_MEM_BAR_SIZE PPC_BITMASK(22, 35) +#define NPU3_GPU_MEM_BAR_SL_MODE PPC_BIT(36) +#define NPU3_GPU_MEM_BAR_4T_LIMIT PPC_BIT(37) +#define NPU3_GPU_MEM_BAR_4T_SELECT PPC_BITMASK(38, 39) +#define NPU3_GPU_MEM_BAR_MODE PPC_BITMASK(40, 43) +#define NPU3_GPU_MEM_BAR_POISON PPC_BIT(45) +#define NPU3_GPU_MEM_BAR_CHIP_EQ_GROUP PPC_BIT(49) +#define NPU3_NTL_BAR(brk) (NPU3_BLOCK_CQ_SM(0) + 0x1b8 + (brk) * 8) +#define NPU3_NTL_BAR_ENABLE PPC_BIT(0) +#define NPU3_NTL_BAR_ADDR PPC_BITMASK(3, 35) +#define NPU3_NTL_BAR_SIZE PPC_BITMASK(39, 43) +#define NPU3_NTL_BAR_SIZE_128K 1 +#define NPU3_MMIO_BAR (NPU3_BLOCK_CQ_SM(0) + 0x1e0) +#define NPU3_MMIO_BAR_ENABLE PPC_BIT(0) +#define NPU3_MMIO_BAR_ADDR PPC_BITMASK(3, 27) +#define NPU3_GENID_BAR (NPU3_BLOCK_CQ_SM(0) + 0x1e8) +#define NPU3_GENID_BAR_ENABLE PPC_BIT(0) +#define NPU3_GENID_BAR_ADDR PPC_BITMASK(3, 32) +#define NPU3_RELAXED_SRC(n) (NPU3_BLOCK_CQ_SM(0) + 0x1f0 + (n) * 8) +#define NPU3_RELAXED_SRC_MAX 4 +#define NPU3_RELAXED_SRC_TAG PPC_BITMASK(0, 13) +#define NPU3_RELAXED_SRC_GRPCHP PPC_BITMASK(0, 6) +#define NPU3_RELAXED_SRC_PEC PPC_BITMASK(12, 13) +#define NPU3_RELAXED_SRC_TAGMASK PPC_BITMASK(14, 27) +#define NPU3_RELAXED_SRC_MASK_NPU PPC_BIT(28) +#define NPU3_RELAXED_SRC_MASK_PCIE PPC_BIT(29) +#define NPU3_RELAXED_SRC_MASK_L2L3 PPC_BIT(30) +#define NPU3_RELAXED_SRC_RDSTART PPC_BITMASK(32, 39) +#define NPU3_RELAXED_SRC_RDEND PPC_BITMASK(40, 47) +#define NPU3_RELAXED_SRC_WRSTART PPC_BITMASK(48, 55) +#define NPU3_RELAXED_SRC_WREND PPC_BITMASK(56, 63) +#define NPU3_RELAXED_CFG2(brk) (NPU3_BLOCK_CQ_SM(0) + 0x230 + (brk) * 8) +#define NPU3_RELAXED_CFG2_CMD_CL_DMA_W PPC_BIT(0) +#define NPU3_RELAXED_CFG2_CMD_CL_DMA_W_HP PPC_BIT(1) +#define NPU3_RELAXED_CFG2_CMD_CL_DMA_INJ PPC_BIT(2) +#define NPU3_RELAXED_CFG2_CMD_PR_DMA_INJ PPC_BIT(3) +#define NPU3_RELAXED_CFG2_CMD_DMA_PR_W PPC_BIT(4) +#define NPU3_RELAXED_CFG2_CMD_CL_RD_NC_F0 PPC_BIT(5) +#define NPU3_RELAXED_CFG2_SRC_WRENA(src) PPC_BIT(32 + (src) * 4) +#define NPU3_RELAXED_CFG2_SRC_RDENA(src) PPC_BIT(33 + (src) * 4) +#define NPU3_RELAXED_CFG2_SRC_AWENA(src) PPC_BIT(34 + (src) * 4) +#define NPU3_RELAXED_CFG2_SRC_ARENA(src) PPC_BIT(35 + (src) * 4) + +/* CQ_CTL block registers */ +#define NPU3_CTL_MISC_CFG0 (NPU3_BLOCK_CQ_CTL + 0x000) +#define NPU3_CTL_MISC_CFG1 (NPU3_BLOCK_CQ_CTL + 0x008) +#define NPU3_CTL_MISC_CFG2 (NPU3_BLOCK_CQ_CTL + 0x010) +#define NPU3_CTL_MISC_CFG2_OCAPI_MODE PPC_BITMASK(0, 4) +#define NPU3_CTL_MISC_CFG2_NVLINK_MODE PPC_BITMASK(5, 9) +#define NPU3_CTL_MISC_CFG3 (NPU3_BLOCK_CQ_CTL + 0x018) +#define NPU3_CTL_BDF2PE_CFG(n) (NPU3_BLOCK_CQ_CTL + 0x180 + (n) * 8) +#define NPU3_CTL_BDF2PE_CFG_ENABLE PPC_BIT(0) +#define NPU3_CTL_BDF2PE_CFG_PE PPC_BITMASK(4, 7) +#define NPU3_CTL_BDF2PE_CFG_BDF PPC_BITMASK(8, 23) + +/* CQ_DAT block registers */ +#define NPU3_DAT_MISC_CFG1 (NPU3_BLOCK_CQ_DAT + 0x008) +#define NPU3_DAT_MISC_CFG1_OCAPI_MODE PPC_BITMASK(40, 44) +#define NPU3_DAT_MISC_CFG1_NVLINK_MODE PPC_BITMASK(45, 49) + +/* NTL block registers */ +#define NPU3_NTL_MISC_CFG2(brk) (NPU3_BLOCK_NTL(brk) + 0x000) +#define NPU3_NTL_MISC_CFG2_BRICK_ENABLE PPC_BIT(0) +#define NPU3_NTL_MISC_CFG2_NDL_RX_PARITY_ENA PPC_BIT(16) +#define NPU3_NTL_MISC_CFG2_NDL_TX_PARITY_ENA PPC_BIT(17) +#define NPU3_NTL_MISC_CFG2_NDL_PRI_PARITY_ENA PPC_BIT(18) +#define NPU3_NTL_MISC_CFG2_RCV_CREDIT_OVERFLOW_ENA PPC_BIT(19) +#define NPU3_NTL_PRI_CFG(brk) (NPU3_BLOCK_NTL(brk) + 0x0b0) +#define NPU3_NTL_PRI_CFG_NDL PPC_BITMASK(1, 2) + +/* NPU_ATS block registers */ +#define NPU3_ATS_IODA_ADDR (NPU3_BLOCK_NPU_ATS + 0x108) +#define NPU3_ATS_IODA_ADDR_AUTO_INC PPC_BIT(0) +#define NPU3_ATS_IODA_ADDR_TBL_SEL PPC_BITMASK(11, 15) +#define NPU3_ATS_IODA_ADDR_TBL_TVT 9 +#define NPU3_ATS_IODA_ADDR_TBL_ADDR PPC_BITMASK(54, 63) +#define NPU3_ATS_IODA_DATA (NPU3_BLOCK_NPU_ATS + 0x110) +#define NPU3_ATS_IODA_TVT_XLAT_ADDR PPC_BITMASK(0, 47) +#define NPU3_ATS_IODA_TVT_TABLE_LEVEL PPC_BITMASK(48, 50) +#define NPU3_ATS_IODA_TVT_TABLE_SIZE PPC_BITMASK(51, 55) +#define NPU3_ATS_IODA_TVT_PAGE_SIZE PPC_BITMASK(59, 63) +#define NPU3_ATS_TCE_KILL (NPU3_BLOCK_NPU_ATS + 0x120) +#define NPU3_ATS_TCE_KILL_ALL PPC_BIT(0) +#define NPU3_ATS_TCE_KILL_ONE PPC_BIT(2) +#define NPU3_ATS_TCE_KILL_PE_NUMBER PPC_BITMASK(4, 7) +#define NPU3_ATS_TCE_KILL_ADDRESS PPC_BITMASK(15, 51) + +/* NPU_XTS block registers */ +#define NPU3_XTS_CFG (NPU3_BLOCK_NPU_XTS + 0x020) +#define NPU3_XTS_CFG_MMIOSD PPC_BIT(1) +#define NPU3_XTS_CFG_TRY_ATR_RO PPC_BIT(6) +#define NPU3_XTS_CFG_OPENCAPI PPC_BIT(15) +#define NPU3_XTS_CFG2 (NPU3_BLOCK_NPU_XTS + 0x028) +#define NPU3_XTS_CFG2_NO_FLUSH_ENA PPC_BIT(49) +#define NPU3_XTS_CFG2_XSL2_ENA PPC_BIT(55) +#define NPU3_XTS_CFG3 (NPU3_BLOCK_NPU_XTS + 0x068) +#define NPU3_XTS_ATSD_HYP(n) (NPU3_BLOCK_NPU_XTS + 0x100 + (n) * 8) +#define NPU3_XTS_ATSD_HYP_MSR_HV PPC_BIT(51) +#define NPU3_XTS_ATSD_HYP_LPARID PPC_BITMASK(52, 63) +#define NPU3_XTS_BDF_MAP(n) (NPU3_BLOCK_NPU_XTS + 0x4000 + (n) * 8) +#define NPU3_XTS_BDF_MAP_MAX 16 +#define NPU3_XTS_BDF_MAP_VALID PPC_BIT(0) +#define NPU3_XTS_BDF_MAP_UNFILT PPC_BIT(1) +#define NPU3_XTS_BDF_MAP_STACK PPC_BITMASK(4, 6) +#define NPU3_XTS_BDF_MAP_BRICK PPC_BITMASK(7, 9) +#define NPU3_XTS_BDF_MAP_BDF PPC_BITMASK(16, 31) +#define NPU3_XTS_BDF_MAP_XLAT PPC_BITMASK(39, 40) +#define NPU3_XTS_BDF_MAP_LPCR_PS PPC_BITMASK(41, 43) +#define NPU3_XTS_BDF_MAP_LPCR_ISL PPC_BIT(44) +#define NPU3_XTS_BDF_MAP_LPCR_TC PPC_BIT(45) +#define NPU3_XTS_BDF_MAP_LPCR_SC PPC_BIT(46) +#define NPU3_XTS_BDF_MAP_LPCR_BOT PPC_BIT(47) +#define NPU3_XTS_BDF_MAP_LPARSHORT PPC_BITMASK(48, 51) +#define NPU3_XTS_BDF_MAP_LPARID PPC_BITMASK(52, 63) +#define NPU3_XTS_PID_MAP(n) (NPU3_BLOCK_NPU_XTS + 0x8000 + (n) * 32) +#define NPU3_XTS_PID_MAP_VALID_ATRGPA0 PPC_BIT(0) +#define NPU3_XTS_PID_MAP_VALID_ATRGPA1 PPC_BIT(1) +#define NPU3_XTS_PID_MAP_VALID_ATSD PPC_BIT(2) +#define NPU3_XTS_PID_MAP_MSR PPC_BITMASK(25, 31) +#define NPU3_XTS_PID_MAP_MSR_DR PPC_BIT(25) +#define NPU3_XTS_PID_MAP_MSR_TA PPC_BIT(26) +#define NPU3_XTS_PID_MAP_MSR_HV PPC_BIT(27) +#define NPU3_XTS_PID_MAP_MSR_PR PPC_BIT(28) +#define NPU3_XTS_PID_MAP_MSR_US PPC_BIT(29) +#define NPU3_XTS_PID_MAP_MSR_SF PPC_BIT(30) +#define NPU3_XTS_PID_MAP_MSR_UV PPC_BIT(31) +#define NPU3_XTS_PID_MAP_LPARSHORT PPC_BITMASK(40, 43) +#define NPU3_XTS_PID_MAP_PID PPC_BITMASK(44, 63) + +/* NPU_MISC block registers */ +#define NPU3_MISC_CFG (NPU3_BLOCK_NPU_MISC + 0x030) +#define NPU3_MISC_CFG_IPI_PS PPC_BIT(11) +#define NPU3_MISC_CFG_IPI_PS_64K 1 +#define NPU3_MISC_CFG_IPI_OS PPC_BIT(12) +#define NPU3_MISC_CFG_IPI_OS_AIX 0 +#define NPU3_MISC_CFG_IPI_OS_LINUX 1 +#define NPU3_MISC_INT_BAR (NPU3_BLOCK_NPU_MISC + 0x098) +#define NPU3_MISC_INT_BAR_ADDR PPC_BITMASK(0, 39) +#define NPU3_MISC_BDF2PE_CFG(n) (NPU3_BLOCK_NPU_MISC + 0x100 + (n) * 8) +#define NPU3_MISC_BDF2PE_CFG_ENABLE PPC_BIT(0) +#define NPU3_MISC_BDF2PE_CFG_PE PPC_BITMASK(4, 7) +#define NPU3_MISC_BDF2PE_CFG_BDF PPC_BITMASK(8, 23) +#define NPU3_MISC_PESTB_DATA(pe) (NPU3_BLOCK_NPU_MISC + 0x200 + (pe) * 8) +#define NPU3_MISC_PESTB_DATA_DMA_STOPPED_STATE PPC_BIT(0) + +/* NPU_XTS_ATSD block registers */ +#define NPU3_XTS_ATSD_LAUNCH(n) (NPU3_BLOCK_NPU_XTS_ATSD(n) + 0x000) +#define NPU3_XTS_ATSD_MAX 16 + +#endif /* __NPU3_REGS_H */ diff --git a/roms/skiboot/include/npu3.h b/roms/skiboot/include/npu3.h new file mode 100644 index 000000000..dda60ae1c --- /dev/null +++ b/roms/skiboot/include/npu3.h @@ -0,0 +1,192 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NPU3_H +#define __NPU3_H + +#include <phys-map.h> +#include <pci.h> +#include <npu3-regs.h> +#include <phb4.h> + +enum npu3_dev_type { + NPU3_DEV_TYPE_UNKNOWN = 0, + NPU3_DEV_TYPE_NVLINK, + NPU3_DEV_TYPE_ANY = INT_MAX +}; + +/* Information about a currently running hw procedure */ +struct npu3_procedure { + uint16_t number; + uint16_t step; + uint32_t status; + unsigned long timeout; +}; + +/* Used to expose a hardware BAR (or logical slice of it) outside skiboot */ +struct npu3_bar { + bool enable; + uint64_t addr; + uint64_t size; + uint64_t trap; +}; + +struct npu3_dev_nvlink { + /* + * PCI virtual device. BDFN is allocated based on NPU association. + * Links connected to the same NPU will be exposed as different + * functions of the same bus/device. + */ + struct pci_virt_device *pvd; + + /* The PCI device created from pvd */ + const char *loc_code; + struct pci_device *pd; + + /* The associated GPU device */ + struct pci_device *gpu; +}; + +struct npu3_dev { + enum npu3_dev_type type; + uint32_t index; + struct dt_node *dn; + struct npu3 *npu; + struct npu3_procedure proc; + uint64_t link_speed; + + struct npu3_bar ntl_bar; + struct npu3_bar genid_bar; + + /* Associated PHY information */ + uint32_t ob_chiplet; + uint32_t phy_lane_mask; + + /* For NPU3_DEV_TYPE_NVLINK */ + struct npu3_dev_nvlink nvlink; +}; + +struct npu3_nvlink { + struct phb phb; + uint32_t ctx_ref[NPU3_XTS_BDF_MAP_MAX]; +}; + +#define NPU3_LINKS_PER_NPU 4 + +struct npu3 { + uint32_t index; + struct dt_node *dt_node; + uint32_t chip_id; + uint64_t xscom_base; + + /* Global MMIO window (all NPU regs) */ + uint64_t regs[2]; + + uint32_t irq_base; + struct lock lock; + bool tx_zcal_complete; + + struct npu3_dev devices[NPU3_LINKS_PER_NPU]; + + /* Shared by any NPU3_DEV_TYPE_NVLINK devices */ + struct npu3_nvlink nvlink; +}; + +static inline struct npu3 *npu3_phb_to_npu(struct phb *phb) +{ + assert(phb->phb_type == phb_type_npu_v3); + return container_of(phb, struct npu3, nvlink.phb); +} + +/* Chip-scope index of the link */ +static inline uint32_t npu3_chip_dev_index(struct npu3_dev *dev) +{ + return dev->npu->index * NPU3_LINKS_PER_NPU + dev->index; +} + +struct npu3_dev *npu3_next_dev(struct npu3 *npu, struct npu3_dev *dev, + enum npu3_dev_type type); + +#define npu3_for_each_dev_type(dev, npu, type) \ + for (dev = NULL; (dev = npu3_next_dev(npu, dev, type));) + +#define npu3_for_each_nvlink_dev(dev, npu) \ + npu3_for_each_dev_type(dev, npu, NPU3_DEV_TYPE_NVLINK) + +#define npu3_for_each_dev(dev, npu) \ + npu3_for_each_dev_type(dev, npu, NPU3_DEV_TYPE_ANY) + +struct npu3 *npu3_next_nvlink_npu(struct npu3 *npu, uint32_t chip_id); + +#define npu3_for_each_chip_nvlink_npu(npu, chip_id) \ + for (npu = NULL; (npu = npu3_next_nvlink_npu(npu, chip_id));) + +#define NPU3_ANY_CHIP INT_MAX +#define npu3_for_each_nvlink_npu(npu) \ + npu3_for_each_chip_nvlink_npu(npu, NPU3_ANY_CHIP) + +void npu3_init_nvlink(struct npu3 *npu); +void npu3_dev_enable_bars(struct npu3_dev *dev, bool enable); +int64_t npu3_dev_reset(struct npu3_dev *dev); + +uint32_t npu3_chip_possible_gpus(void); +int32_t npu3_dev_gpu_index(struct npu3_dev *dev); + +/* NPU RING register access */ +void npu3_write(struct npu3 *npu, uint64_t reg, uint64_t val); +uint64_t npu3_read(struct npu3 *npu, uint64_t reg); +void npu3_write_4b(struct npu3 *npu, uint64_t reg, uint32_t val); +uint32_t npu3_read_4b(struct npu3 *npu, uint64_t reg); + +/* Link flags */ +#define NPU3_DEV_PCI_LINKED 0x1 +#define NPU3_DEV_DL_RESET 0x2 + +void npu3_pvd_flag_set(struct npu3_dev *dev, uint8_t flag); +void npu3_pvd_flag_clear(struct npu3_dev *dev, uint8_t flag); + +/* PHY procedures */ +#define NPU3_PROC_STATUS_MASK 0xc000000f +#define NPU3_PROC_INPROGRESS (1 << 31) +#define NPU3_PROC_COMPLETE (1 << 30) +#define NPU3_PROC_NEXT (1 << 29) +#define NPU3_PROC_FAILED 2 +#define NPU3_PROC_ABORTED 3 +#define NPU3_PROC_UNSUPPORTED 4 + +void npu3_dev_procedure_init(struct npu3_dev *dev, uint32_t pnum); +uint32_t npu3_dev_procedure_status(struct npu3_dev *dev); + +/* OPAL entry points */ +int64_t npu3_init_context(struct phb *phb, uint64_t msr, uint64_t bdf); +int64_t npu3_destroy_context(struct phb *phb, uint64_t bdf); +int64_t npu3_map_lpar(struct phb *phb, uint64_t bdf, uint64_t lparid, + uint64_t lpcr); +int64_t npu3_set_relaxed_order(struct phb *phb, uint32_t gcid, int pec, + bool enable); + +#define NPU3_PHB_INDEX_BASE 6 /* immediately after real PHBs */ +static inline int npu3_get_phb_index(unsigned int npu_index) +{ + return NPU3_PHB_INDEX_BASE + npu_index; +} + +static inline int npu3_get_opal_id(unsigned int chip_id, unsigned int index) +{ + return phb4_get_opal_id(chip_id, index); +} + +#endif /* __NPU3_H */ diff --git a/roms/skiboot/include/nvram.h b/roms/skiboot/include/nvram.h new file mode 100644 index 000000000..eaaa443e0 --- /dev/null +++ b/roms/skiboot/include/nvram.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __NVRAM_H +#define __NVRAM_H + +int nvram_format(void *nvram_image, uint32_t nvram_size); +int nvram_check(void *nvram_image, uint32_t nvram_size); +void nvram_reinit(void); +bool nvram_validate(void); +bool nvram_has_loaded(void); +bool nvram_wait_for_load(void); + +const char *nvram_query_safe(const char *name); +const char *nvram_query_dangerous(const char *name); +bool nvram_query_eq_safe(const char *key, const char *value); +bool nvram_query_eq_dangerous(const char *key, const char *value); + +#endif /* __NVRAM_H */ diff --git a/roms/skiboot/include/nx.h b/roms/skiboot/include/nx.h new file mode 100644 index 000000000..c42d165e9 --- /dev/null +++ b/roms/skiboot/include/nx.h @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __NX_H +#define __NX_H + +/*************************************/ +/* Register addresses and bit fields */ +/*************************************/ + +#define NX_P8_SAT(sat, offset) XSCOM_SAT(0xc, sat, offset) +#define NX_P9_SAT(sat, offset) XSCOM_SAT(0x4, sat, offset) + +/* Random Number Generator */ +#define NX_P8_RNG_BAR NX_P8_SAT(0x2, 0x0d) +#define NX_P9_RNG_BAR NX_P9_SAT(0x2, 0x0d) +#define NX_P8_RNG_BAR_ADDR PPC_BITMASK(14, 51) +/* + * Section 5.30 of P9 NX Workbook Version 2.42 shows RNG BAR as: + * 0:7 unused + * 8:51 RNG BAR Base Address for RNG reads + * 52 Enable bit for RNG BAR + * 53:63 Unused + * + * Following macros encode that info. + */ +#define NX_P9_RNG_BAR_ADDR PPC_BITMASK(8, 51) +#define NX_RNG_BAR_SIZE PPC_BITMASK(53, 55) +#define NX_RNG_BAR_ENABLE PPC_BIT(52) + +#define NX_P8_RNG_CFG NX_P8_SAT(0x2, 0x12) +#define NX_RNG_CFG_ENABLE PPC_BIT(63) + +/* Symmetric Crypto */ +#define NX_P8_SYM_CFG NX_P8_SAT(0x2, 0x0a) +#define NX_SYM_CFG_CI PPC_BITMASK(2, 14) +#define NX_SYM_CFG_CT PPC_BITMASK(18, 23) +#define NX_SYM_CFG_FC_ENABLE PPC_BITMASK(32, 39) +#define NX_SYM_CFG_ENABLE PPC_BIT(63) + +/* Asymmetric Crypto */ +#define NX_P8_ASYM_CFG NX_P8_SAT(0x2, 0x0b) +#define NX_ASYM_CFG_CI PPC_BITMASK(2, 14) +#define NX_ASYM_CFG_CT PPC_BITMASK(18, 23) +#define NX_ASYM_CFG_FC_ENABLE PPC_BITMASK(32, 52) +#define NX_ASYM_CFG_ENABLE PPC_BIT(63) + +/* 842 Compression. CFG is used only on P8 */ +#define NX_P8_842_CFG NX_P8_SAT(0x2, 0x0c) +#define NX_842_CFG_CI PPC_BITMASK(2, 14) +#define NX_842_CFG_CT PPC_BITMASK(18, 23) +#define NX_842_CFG_FC_ENABLE PPC_BITMASK(32, 36) +#define NX_842_CFG_ENABLE PPC_BIT(63) + +/* DMA */ +#define NX_P8_DMA_CFG NX_P8_SAT(0x1, 0x02) +#define NX_P9_DMA_CFG NX_P9_SAT(0x1, 0x02) +#define NX_DMA_CFG_GZIP_COMPRESS_MAX_RR PPC_BITMASK(8, 11) +#define NX_DMA_CFG_GZIP_DECOMPRESS_MAX_RR PPC_BITMASK(12, 15) +#define NX_DMA_CFG_GZIP_COMPRESS_PREFETCH PPC_BIT(16) +#define NX_DMA_CFG_GZIP_DECOMPRESS_PREFETCH PPC_BIT(17) +#define NX_DMA_CFG_842_COMPRESS_PREFETCH PPC_BIT(23) +#define NX_DMA_CFG_842_DECOMPRESS_PREFETCH PPC_BIT(24) +#define NX_DMA_CFG_AES_SHA_MAX_RR PPC_BITMASK(25, 28) +#define NX_DMA_CFG_AMF_MAX_RR PPC_BITMASK(29, 32) +#define NX_DMA_CFG_842_COMPRESS_MAX_RR PPC_BITMASK(33, 36) +#define NX_DMA_CFG_842_DECOMPRESS_MAX_RR PPC_BITMASK(37, 40) +#define NX_DMA_CFG_AES_SHA_CSB_WR PPC_BITMASK(41, 42) +#define NX_DMA_CFG_AES_SHA_COMPLETION_MODE PPC_BITMASK(43, 44) +#define NX_DMA_CFG_AES_SHA_CPB_WR PPC_BITMASK(45, 46) +#define NX_DMA_CFG_AES_SHA_OUTPUT_DATA_WR PPC_BIT(47) +#define NX_DMA_CFG_AMF_CSB_WR PPC_BITMASK(49, 50) +#define NX_DMA_CFG_AMF_COMPLETION_MODE PPC_BITMASK(51, 52) +#define NX_DMA_CFG_AMF_CPB_WR PPC_BITMASK(53, 54) +#define NX_DMA_CFG_AMF_OUTPUT_DATA_WR PPC_BIT(55) +#define NX_DMA_CFG_842_SPBC PPC_BIT(56) +#define NX_DMA_CFG_842_CSB_WR PPC_BITMASK(57, 58) +#define NX_DMA_CFG_842_COMPLETION_MODE PPC_BITMASK(59, 60) +#define NX_DMA_CFG_842_CPB_WR PPC_BITMASK(61, 62) +#define NX_DMA_CFG_842_OUTPUT_DATA_WR PPC_BIT(63) + +/* Engine Enable Register */ +#define NX_P8_EE_CFG NX_P8_SAT(0x1, 0x01) +#define NX_P9_EE_CFG NX_P9_SAT(0x1, 0x01) +#define NX_EE_CFG_EFUSE PPC_BIT(0) +#define NX_EE_CFG_CH7 PPC_BIT(53) /* AMF */ +#define NX_EE_CFG_CH6 PPC_BIT(54) /* AMF */ +#define NX_EE_CFG_CH5 PPC_BIT(55) /* AMF */ +#define NX_EE_CFG_CH4 PPC_BIT(56) /* AMF */ +#define NX_EE_CFG_CH3 PPC_BIT(57) /* SYM */ +#define NX_EE_CFG_CH2 PPC_BIT(58) /* SYM */ +#define NX_P9_EE_CFG_CH4 PPC_BIT(61) /* gzip */ +#define NX_EE_CFG_CH1 PPC_BIT(62) /* 842 */ +#define NX_EE_CFG_CH0 PPC_BIT(63) /* 842 */ + +/* Max byte count register - P9 and later */ +#define NX_P9_842_MAX_BYTE_COUNT NX_P9_SAT(0x1, 0x19) +#define NX_P9_GZIP_MAX_BYTE_COUNT NX_P9_SAT(0x1, 0x1b) + +#define NX_P9_DMA_VAS_MMIO_BAR NX_P9_SAT(0x1, 0x1e) +#define NX_P9_DMA_VAS_MMIO_ADDR PPC_BITMASK(8, 38) + +/* PowerBus Registers */ +#define NX_P8_CRB_IQ NX_P8_SAT(0x2, 0x0f) +#define NX_CRB_IQ_SYM PPC_BITMASK(0, 2) +#define NX_CRB_IQ_ASYM PPC_BITMASK(3, 5) + +/* UMAC registers - P9 and later */ +#define NX_P9_842_HIGH_PRI_RX_FIFO_BAR NX_P9_SAT(0x3, 0x00) +#define NX_P9_GZIP_HIGH_PRI_RX_FIFO_BAR NX_P9_SAT(0x3, 0x02) +#define NX_P9_842_NORMAL_PRI_RX_FIFO_BAR NX_P9_SAT(0x3, 0x09) +#define NX_P9_GZIP_NORMAL_PRI_RX_FIFO_BAR NX_P9_SAT(0x3, 0x0b) +#define NX_P9_RX_FIFO_BAR_ADDR PPC_BITMASK(8, 53) +#define NX_P9_RX_FIFO_BAR_SIZE PPC_BITMASK(54, 56) + +#define NX_P9_842_HIGH_PRI_RX_FIFO_NOTIFY_MATCH NX_P9_SAT(0x3, 0x06) +#define NX_P9_GZIP_HIGH_PRI_RX_FIFO_NOTIFY_MATCH NX_P9_SAT(0x3, 0x08) +#define NX_P9_842_NORMAL_PRI_RX_FIFO_NOTIFY_MATCH NX_P9_SAT(0x3, 0x0f) +#define NX_P9_GZIP_NORMAL_PRI_RX_FIFO_NOTIFY_MATCH NX_P9_SAT(0x3, 0x11) +#define NX_P9_RX_FIFO_NOTIFY_MATCH_LPID PPC_BITMASK(4, 15) +#define NX_P9_RX_FIFO_NOTIFY_MATCH_PID PPC_BITMASK(20, 39) +#define NX_P9_RX_FIFO_NOTIFY_MATCH_TID PPC_BITMASK(44, 59) +#define NX_P9_RX_FIFO_NOTIFY_MATCH_MATCH_ENABLE PPC_BIT(63) + +#define NX_P9_842_HIGH_PRI_RX_FIFO_CTRL NX_P9_SAT(0x3, 0x03) +#define NX_P9_GZIP_HIGH_PRI_RX_FIFO_CTRL NX_P9_SAT(0x3, 0x05) +#define NX_P9_842_NORMAL_PRI_RX_FIFO_CTRL NX_P9_SAT(0x3, 0x0c) +#define NX_P9_GZIP_NORMAL_PRI_RX_FIFO_CTRL NX_P9_SAT(0x3, 0x0e) +#define NX_P9_RX_FIFO_CTRL_READ_OFFSET PPC_BITMASK(4, 11) +#define NX_P9_RX_FIFO_CTRL_QUEUED PPC_BITMASK(15, 23) +#define NX_P9_RX_FIFO_CTRL_HPRI_MAX_READ PPC_BITMASK(27, 35) + +#define NX_P9_UMAC_TX_WINDOW_CONTEXT_BAR NX_P9_SAT(0x3, 0x12) +#define NX_P9_UMAC_TX_WINDOW_CONTEXT_ADDR PPC_BITMASK(8, 40) + +#define NX_P9_UMAC_VAS_MMIO_BAR NX_P9_SAT(0x3, 0x14) +#define NX_P9_UMAC_VAS_MMIO_ADDR PPC_BITMASK(8, 38) + +#define NX_P9_UMAC_STATUS_CTRL NX_P9_SAT(0x3, 0x15) +#define NX_P9_UMAC_STATUS_CTRL_CRB_ENABLE PPC_BIT(1) + +#define NX_P9_ERAT_STATUS_CTRL NX_P9_SAT(0x3, 0x16) + +/* Introduced in P10, but P10 NX SCOM address is same as P9 */ +#define NX_P10_VAS_RMA_WRITE_BAR NX_P9_SAT(0x3, 0x19) + +/* NX Status Register */ +#define NX_P8_STATUS NX_P8_SAT(0x1, 0x00) +#define NX_P9_STATUS NX_P9_SAT(0x1, 0x00) /* DMA Status register */ +#define NX_STATUS_HMI_ACTIVE PPC_BIT(54) +#define NX_STATUS_PBI_IDLE PPC_BIT(55) +#define NX_STATUS_DMA_CH0_IDLE PPC_BIT(56) +#define NX_STATUS_DMA_CH1_IDLE PPC_BIT(57) +#define NX_STATUS_DMA_CH2_IDLE PPC_BIT(58) +#define NX_STATUS_DMA_CH3_IDLE PPC_BIT(59) +#define NX_STATUS_DMA_CH4_IDLE PPC_BIT(60) +#define NX_STATUS_DMA_CH5_IDLE PPC_BIT(61) +#define NX_STATUS_DMA_CH6_IDLE PPC_BIT(62) +#define NX_STATUS_DMA_CH7_IDLE PPC_BIT(63) + +/* Channel Status Registers */ +#define NX_P8_CH_CRB(ch) NX_P8_SAT(0x1, 0x03 + ((ch) * 2)) +#define NX_P9_CH_CRB(ch) NX_P9_SAT(0x1, 0x03 + ((ch) * 2)) +#define NX_P8_CH_STATUS(ch) NX_P8_SAT(0x1, 0x04 + ((ch) * 2)) +#define NX_CH_STATUS_ABORT PPC_BIT(0) +#define NX_CH_STATUS_CCB_VALID PPC_BIT(4) +#define NX_CH_STATUS_CCB_CM PPC_BITMASK(5, 7) +#define NX_CH_STATUS_CCB_PRIO PPC_BITMASK(8, 15) +#define NX_CH_STATUS_CCB_SN PPC_BITMASK(16, 31) +#define NX_CH_STATUS_VALID PPC_BIT(32) +#define NX_CH_STATUS_LPID PPC_BITMASK(38, 47) +#define NX_CH_STATUS_CCB_ISN PPC_BITMASK(50, 63) +#define NX_CH_STATUS_CRB_SJT PPC_BITMASK(50, 63) + +/* Kill Register */ +#define NX_P8_CRB_KILL NX_P8_SAT(0x1, 0x13) +#define NX_P9_CRB_KILL NX_P9_SAT(0x1, 0x13) +#define NX_CRB_KILL_LPID_KILL PPC_BIT(0) +#define NX_CRB_KILL_LPID PPC_BITMASK(6, 15) +#define NX_CRB_KILL_ISN_KILL PPC_BIT(16) +#define NX_CRB_KILL_SJT_KILL PPC_BIT(17) +#define NX_CRB_KILL_ISN PPC_BITMASK(18, 31) +#define NX_CRB_KILL_SJT PPC_BITMASK(18, 31) +#define NX_CRB_KILL_DONE PPC_BIT(32) +#define NX_CRB_KILL_PBI_LOC PPC_BITMASK(40, 47) +#define NX_CRB_KILL_PREFETCH_CH PPC_BITMASK(48, 55) +#define NX_CRB_KILL_ALG_CH PPC_BITMASK(56, 63) + +/* Fault Isolation Registers (FIR) */ +#define NX_P8_DE_FIR_DATA NX_P8_SAT(0x4, 0x00) +#define NX_P9_DE_FIR_DATA NX_P9_SAT(0x4, 0x00) +#define NX_P8_DE_FIR_DATA_CLR NX_P8_SAT(0x4, 0x01) +#define NX_P9_DE_FIR_DATA_CLR NX_P9_SAT(0x4, 0x01) +#define NX_P8_DE_FIR_DATA_SET NX_P8_SAT(0x4, 0x02) +#define NX_P9_DE_FIR_DATA_SET NX_P9_SAT(0x4, 0x02) +#define NX_P8_DE_FIR_MASK NX_P8_SAT(0x4, 0x03) +#define NX_P9_DE_FIR_MASK NX_P9_SAT(0x4, 0x03) +#define NX_P8_DE_FIR_MASK_CLR NX_P8_SAT(0x4, 0x04) +#define NX_P9_DE_FIR_MASK_CLR NX_P9_SAT(0x4, 0x04) +#define NX_P8_DE_FIR_MASK_SET NX_P8_SAT(0x4, 0x05) +#define NX_P9_DE_FIR_MASK_SET NX_P9_SAT(0x4, 0x05) +#define NX_P8_DE_FIR_ACTION0 NX_P8_SAT(0x4, 0x06) +#define NX_P9_DE_FIR_ACTION0 NX_P9_SAT(0x4, 0x06) +#define NX_P8_DE_FIR_ACTION1 NX_P8_SAT(0x4, 0x07) +#define NX_P9_DE_FIR_ACTION1 NX_P9_SAT(0x4, 0x07) +#define NX_P8_DE_FIR_WOF NX_P8_SAT(0x4, 0x08) +#define NX_P9_PB_FIR_DATA NX_P9_SAT(0x2, 0x00) +#define NX_P8_PB_FIR_DATA NX_P8_SAT(0x2, 0x00) +#define NX_P8_PB_FIR_DATA_CLR NX_P8_SAT(0x2, 0x01) +#define NX_P9_PB_FIR_DATA_CLR NX_P9_SAT(0x2, 0x01) +#define NX_P8_PB_FIR_DATA_SET NX_P8_SAT(0x2, 0x02) +#define NX_P9_PB_FIR_DATA_SET NX_P9_SAT(0x2, 0x02) +#define NX_P8_PB_FIR_MASK NX_P8_SAT(0x2, 0x03) +#define NX_P9_PB_FIR_MASK NX_P9_SAT(0x2, 0x03) +#define NX_P8_PB_FIR_MASK_CLR NX_P8_SAT(0x2, 0x04) +#define NX_P9_PB_FIR_MASK_CLR NX_P9_SAT(0x2, 0x04) +#define NX_P8_PB_FIR_MASK_SET NX_P8_SAT(0x2, 0x05) +#define NX_P9_PB_FIR_MASK_SET NX_P9_SAT(0x2, 0x05) +#define NX_P8_PB_FIR_ACTION0 NX_P8_SAT(0x2, 0x06) +#define NX_P9_PB_FIR_ACTION0 NX_P9_SAT(0x2, 0x06) +#define NX_P8_PB_FIR_ACTION1 NX_P8_SAT(0x2, 0x07) +#define NX_P9_PB_FIR_ACTION1 NX_P9_SAT(0x2, 0x07) +#define NX_P8_PB_FIR_WOF NX_P8_SAT(0x2, 0x08) +#define NX_FIR_SHM_INV PPC_BIT(1) +#define NX_FIR_CH0_ECC_CE PPC_BIT(4) +#define NX_FIR_CH0_ECC_UE PPC_BIT(5) +#define NX_FIR_CH1_ECC_CE PPC_BIT(6) +#define NX_FIR_CH1_ECC_UE PPC_BIT(7) +#define NX_FIR_DMA_NZ_CSB_CC PPC_BIT(8) /* lab use only */ +#define NX_FIR_DMA_ARRAY_ECC_CE PPC_BIT(9) +#define NX_FIR_DMA_RW_ECC_CE PPC_BIT(10) +#define NX_FIR_CH5_ECC_CE PPC_BIT(11) +#define NX_FIR_CH6_ECC_CE PPC_BIT(12) +#define NX_FIR_CH7_ECC_CE PPC_BIT(13) +#define NX_FIR_OTHER_SCOM_ERR PPC_BIT(14) +#define NX_FIR_DMA_INV_STATE PPC_BITMASK(15, 16) +#define NX_FIR_DMA_ARRAY_ECC_UE PPC_BIT(17) +#define NX_FIR_DMA_RW_ECC_UE PPC_BIT(18) +#define NX_FIR_HYP PPC_BIT(19) /* for HYP to force HMI */ +#define NX_FIR_CH0_INV_STATE PPC_BIT(20) +#define NX_FIR_CH1_INV_STATE PPC_BIT(21) +#define NX_FIR_CH2_INV_STATE PPC_BIT(22) +#define NX_FIR_CH3_INV_STATE PPC_BIT(23) +#define NX_FIR_CH4_INV_STATE PPC_BIT(24) +#define NX_FIR_CH5_INV_STATE PPC_BIT(25) +#define NX_FIR_CH6_INV_STATE PPC_BIT(26) +#define NX_FIR_CH7_INV_STATE PPC_BIT(27) +#define NX_FIR_CH5_ECC_UE PPC_BIT(28) +#define NX_FIR_CH6_ECC_UE PPC_BIT(29) +#define NX_FIR_CH7_ECC_UE PPC_BIT(30) +#define NX_FIR_CRB_UE PPC_BIT(31) +#define NX_FIR_CRB_SUE PPC_BIT(32) +#define NX_FIR_DMA_RW_ECC_SUE PPC_BIT(33) +#define NX_FIR_CH4_ECC_CE PPC_BIT(36) /* P8 only */ +#define NX_FIR_CH5_ECC_UE_2 PPC_BIT(37) /* P8 only */ +#define NX_FIR_P8_PARITY PPC_BITMASK(48, 49) + +/* Rx FIFO is needed for VAS which is available on P9 or later */ +#define RX_FIFO_SIZE 0x8000 + +/**************************************/ +/* Register field values/restrictions */ +/**************************************/ + +/* Arbitrary Coprocessor Type values */ +#define NX_CT_SYM (1) +#define NX_CT_ASYM (2) /* on P8 */ +#define NX_CT_GZIP (2) /* on P9 and later */ +#define NX_CT_842 (3) + +/* Coprocessor Instance counter + * NX workbook, section 5.5.1 + * "Assigning <CT,CI> Values" + * Only on P8 + */ +#define NX_SYM_CFG_CI_MAX (511) +#define NX_SYM_CFG_CI_LSHIFT (2) +#define NX_ASYM_CFG_CI_MAX (127) +#define NX_ASYM_CFG_CI_LSHIFT (4) +#define NX_842_CFG_CI_MAX (511) +#define NX_842_CFG_CI_LSHIFT (2) + +/* DMA configuration values + * NX workbook, section 5.2.3, table 5-4 + * "DMA Configuration Register Bits" + * + * These values can be used for the AES/SHA, AMF, and 842 DMA + * configuration fields in the DMA configuration register. + * + * Abbreviations used below: + * pDMA - "partial DMA write" + * fDMA - "full DMA write" + * CI - Cache Inject + */ +/* NX_DMA_CSB_WR values: + * 0 = Always perform 8 or 16 byte pDMA + * 1 = Do 128 byte CI if CSB at end of cache line, else pDMA + * 2 = Do 128 byte fDMA if CSB at end of cache line, else pDMA + */ +#define NX_DMA_CSB_WR_PDMA (0) +#define NX_DMA_CSB_WR_CI (1) +#define NX_DMA_CSB_WR_FDMA (2) +/* NX_DMA_COMPLETION_MODE values: + * 0 = Always perform 8 byte pDMA + * 1 = Do 128 byte CI, replicating 8 bytes across entire 128 byte cache line + * 2 = Do 128 byte fDMA, replicating 8 bytes across entire 128 byte cache line + */ +#define NX_DMA_COMPLETION_MODE_PDMA (0) +#define NX_DMA_COMPLETION_MODE_CI (1) +#define NX_DMA_COMPLETION_MODE_FDMA (2) +/* NX_DMA_CPB_WR values: + * 0 = Always do pDMA or fDMA, based on number of bytes and alignment + * 1 = Always do pDMA on non-aligned cache lines, fDMA on aligned cache lines + * (may store dummy data at the end of the aligned data) + * 2 = Do 128 byte CI when writing 128 aligned bytes, else pDMA + * 3 = Do 128 byte CI when writing aligned cache lines, else pDMA + * (may store dummy data at the end of the aligned data) + */ +#define NX_DMA_CPB_WR_DMA_NOPAD (0) +#define NX_DMA_CPB_WR_DMA_PAD (1) +#define NX_DMA_CPB_WR_CI_NOPAD (2) +#define NX_DMA_CPB_WR_CI_PAD (3) +/* NX_DMA_OUTPUT_DATA_WR values: + * 0 = Always do pDMA or fDMA, based on number of bytes and alignment + * 1 = Do 128 byte CI when writing 128 aligned bytes, else pDMA + */ +#define NX_DMA_OUTPUT_DATA_WR_DMA (0) +#define NX_DMA_OUTPUT_DATA_WR_CI (1) + + +/* + * NX compression configuration settings for 842 (on p8 and later) + * and gzip (p9 and later) engines + */ +#define DMA_COMPRESS_PREFETCH (1) /* enable prefetching */ +#define DMA_DECOMPRESS_PREFETCH (1) /* enable prefetching */ +#define DMA_COMPRESS_MAX_RR (15) /* range 1-15 */ +#define DMA_DECOMPRESS_MAX_RR (15) /* range 1-15 */ +#define DMA_SPBC (1) /* write SPBC in CPB */ + +/******************************/ +/* NX node creation functions */ +/******************************/ + +extern void nx_create_rng_node(struct dt_node *); +extern void nx_create_crypto_node(struct dt_node *); +extern void nx_create_compress_node(struct dt_node *); + +extern void nx_enable_842(struct dt_node *node, u32 gcid, u32 pb_base); +extern void p9_nx_enable_842(struct dt_node *node, u32 gcid, u32 pb_base); +extern void p9_nx_enable_gzip(struct dt_node *node, u32 gcid, u32 pb_base); + +extern int nx_cfg_rx_fifo(struct dt_node *node, const char *compat, + const char *priority, u32 gcid, u32 pid, u32 tid, + u64 umac_bar, u64 umac_notify); + +extern void nx_init(void); + +#endif /* __NX_H */ diff --git a/roms/skiboot/include/occ.h b/roms/skiboot/include/occ.h new file mode 100644 index 000000000..f1a1e2da9 --- /dev/null +++ b/roms/skiboot/include/occ.h @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017-2019 IBM Corp. */ + +#include <chip.h> + +/* OCC Functions */ + +extern void occ_pstates_init(void); +extern void occ_fsp_init(void); +int find_master_and_slave_occ(uint64_t **master, uint64_t **slave, + int *nr_masters, int *nr_slaves); + +/* OCC interrupt for P8 */ +extern void occ_p8_interrupt(uint32_t chip_id); +extern void occ_send_dummy_interrupt(void); + +/* OCC interrupt for P9 */ +extern void occ_p9_interrupt(uint32_t chip_id); + +/* OCC load support */ +extern void occ_poke_load_queue(void); + +/* OCC/Host PNOR ownership */ +enum pnor_owner { + PNOR_OWNER_HOST, + PNOR_OWNER_EXTERNAL, +}; +extern void occ_pnor_set_owner(enum pnor_owner owner); + +/* GPU presence detection */ +bool occ_get_gpu_presence(struct proc_chip *chip, int gpu_num); + +/* OCC Inband Sensors */ +extern bool occ_sensors_init(void); +extern int occ_sensor_read(u32 handle, __be64 *data); +extern int occ_sensor_group_clear(u32 group_hndl, int token); +extern void occ_add_sensor_groups(struct dt_node *sg, __be32 *phandles, + u32 *ptype, int nr_phandles, int chipid); + +extern int occ_sensor_group_enable(u32 group_hndl, int token, bool enable); + +extern bool is_occ_reset(void); + +/* + * OCC Sensor Data + * + * OCC sensor data will use BAR2 (OCC Common is per physical drawer). + * Starting address is at offset 0x00580000 from BAR2 base address. + * Maximum size is 1.5MB. + * + * ------------------------------------------------------------------------- + * | Start (Offset from | End | Size |Description | + * | BAR2 base address) | | | | + * ------------------------------------------------------------------------- + * | 0x00580000 | 0x005A57FF |150kB |OCC 0 Sensor Data Block| + * | 0x005A5800 | 0x005CAFFF |150kB |OCC 1 Sensor Data Block| + * | : | : | : | : | + * | 0x00686800 | 0x006ABFFF |150kB |OCC 7 Sensor Data Block| + * | 0x006AC000 | 0x006FFFFF |336kB |Reserved | + * ------------------------------------------------------------------------- + * + * + * OCC N Sensor Data Block Layout (150kB) + * + * The sensor data block layout is the same for each OCC N. It contains + * sensor-header-block, sensor-names buffer, sensor-readings-ping buffer and + * sensor-readings-pong buffer. + * + * ---------------------------------------------------------------------------- + * | Start (Offset from OCC | End | Size |Description | + * | N Sensor Data Block) | | | | + * ---------------------------------------------------------------------------- + * | 0x00000000 | 0x000003FF |1kB |Sensor Data Header Block | + * | 0x00000400 | 0x0000CBFF |50kB |Sensor Names | + * | 0x0000CC00 | 0x0000DBFF |4kB |Reserved | + * | 0x0000DC00 | 0x00017BFF |40kB |Sensor Readings ping buffer| + * | 0x00017C00 | 0x00018BFF |4kB |Reserved | + * | 0x00018C00 | 0x00022BFF |40kB |Sensor Readings pong buffer| + * | 0x00022C00 | 0x000257FF |11kB |Reserved | + * ---------------------------------------------------------------------------- + * + * Sensor Data Header Block : This is written once by the OCC during + * initialization after a load or reset. Layout is defined in 'struct + * occ_sensor_data_header' + * + * Sensor Names : This is written once by the OCC during initialization after a + * load or reset. It contains static information for each sensor. The number of + * sensors, format version and length of each sensor is defined in + * 'Sensor Data Header Block'. Format of each sensor name is defined in + * 'struct occ_sensor_name'. The first sensor starts at offset 0 followed + * immediately by the next sensor. + * + * Sensor Readings Ping/Pong Buffer: + * There are two 40kB buffers to store the sensor readings. One buffer that + * is currently being updated by the OCC and one that is available to be read. + * Each of these buffers will be of the same format. The number of sensors and + * the format version of the ping and pong buffers is defined in the + * 'Sensor Data Header Block'. + * + * Each sensor within the ping and pong buffers may be of a different format + * and length. For each sensor the length and format is determined by its + * 'struct occ_sensor_name.structure_type' in the Sensor Names buffer. + * + * -------------------------------------------------------------------------- + * | Offset | Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 | + * -------------------------------------------------------------------------- + * | 0x0000 |Valid | Reserved | + * | |(0x01) | | + * -------------------------------------------------------------------------- + * | 0x0008 | Sensor Readings | + * -------------------------------------------------------------------------- + * | : | : | + * -------------------------------------------------------------------------- + * | 0xA000 | End of Data | + * -------------------------------------------------------------------------- + * + */ + +#define MAX_OCCS 8 +#define MAX_CHARS_SENSOR_NAME 16 +#define MAX_CHARS_SENSOR_UNIT 4 + +#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x00580000 +#define OCC_SENSOR_DATA_BLOCK_SIZE 0x00025800 + +/* + * These should match the definitions inside the OCC source: + * occ/src/occ_405/sensor/sensor_info.c + */ + +enum occ_sensor_type { + OCC_SENSOR_TYPE_GENERIC = 0x0001, + OCC_SENSOR_TYPE_CURRENT = 0x0002, + OCC_SENSOR_TYPE_VOLTAGE = 0x0004, + OCC_SENSOR_TYPE_TEMPERATURE = 0x0008, + OCC_SENSOR_TYPE_UTILIZATION = 0x0010, + OCC_SENSOR_TYPE_TIME = 0x0020, + OCC_SENSOR_TYPE_FREQUENCY = 0x0040, + OCC_SENSOR_TYPE_POWER = 0x0080, + OCC_SENSOR_TYPE_PERFORMANCE = 0x0200, +}; + +#define OCC_ENABLED_SENSOR_MASK (OCC_SENSOR_TYPE_GENERIC | \ + OCC_SENSOR_TYPE_CURRENT | \ + OCC_SENSOR_TYPE_VOLTAGE | \ + OCC_SENSOR_TYPE_TIME | \ + OCC_SENSOR_TYPE_TEMPERATURE | \ + OCC_SENSOR_TYPE_POWER | \ + OCC_SENSOR_TYPE_UTILIZATION | \ + OCC_SENSOR_TYPE_FREQUENCY | \ + OCC_SENSOR_TYPE_PERFORMANCE); + +enum occ_sensor_location { + OCC_SENSOR_LOC_SYSTEM = 0x0001, + OCC_SENSOR_LOC_PROCESSOR = 0x0002, + OCC_SENSOR_LOC_PARTITION = 0x0004, + OCC_SENSOR_LOC_MEMORY = 0x0008, + OCC_SENSOR_LOC_VRM = 0x0010, + OCC_SENSOR_LOC_OCC = 0x0020, + OCC_SENSOR_LOC_CORE = 0x0040, + OCC_SENSOR_LOC_GPU = 0x0080, + OCC_SENSOR_LOC_QUAD = 0x0100, +}; + +enum sensor_struct_type { + OCC_SENSOR_READING_FULL = 0x01, + OCC_SENSOR_READING_COUNTER = 0x02, +}; + +/** + * struct occ_sensor_data_header - Sensor Data Header Block + * @valid: When the value is 0x01 it indicates + * that this header block and the sensor + * names buffer are ready + * @version: Format version of this block + * @nr_sensors: Number of sensors in names, ping and + * pong buffer + * @reading_version: Format version of the Ping/Pong buffer + * @names_offset: Offset to the location of names buffer + * @names_version: Format version of names buffer + * @names_length: Length of each sensor in names buffer + * @reading_ping_offset: Offset to the location of Ping buffer + * @reading_pong_offset: Offset to the location of Pong buffer + * @pad/reserved: Unused data + */ +struct occ_sensor_data_header { + u8 valid; + u8 version; + __be16 nr_sensors; + u8 reading_version; + u8 pad[3]; + __be32 names_offset; + u8 names_version; + u8 name_length; + u16 reserved; + __be32 reading_ping_offset; + __be32 reading_pong_offset; +} __attribute__((__packed__)); + +/** + * struct occ_sensor_name - Format of Sensor Name + * @name: Sensor name + * @units: Sensor units of measurement + * @gsid: Global sensor id (OCC) + * @freq: Update frequency + * @scale_factor: Scaling factor + * @type: Sensor type as defined in + * 'enum occ_sensor_type' + * @location: Sensor location as defined in + * 'enum occ_sensor_location' + * @structure_type: Indicates type of data structure used + * for the sensor readings in the ping and + * pong buffers for this sensor as defined + * in 'enum sensor_struct_type' + * @reading_offset: Offset from the start of the ping/pong + * reading buffers for this sensor + * @sensor_data: Sensor specific info + * @pad: Padding to fit the size of 48 bytes. + */ +struct occ_sensor_name { + char name[MAX_CHARS_SENSOR_NAME]; + char units[MAX_CHARS_SENSOR_UNIT]; + __be16 gsid; + __be32 freq; + __be32 scale_factor; + __be16 type; + __be16 location; + u8 structure_type; + __be32 reading_offset; + u8 sensor_data; + u8 pad[8]; +} __attribute__((__packed__)); + +/** + * struct occ_sensor_record - Sensor Reading Full + * @gsid: Global sensor id (OCC) + * @timestamp: Time base counter value while updating + * the sensor + * @sample: Latest sample of this sensor + * @sample_min: Minimum value since last OCC reset + * @sample_max: Maximum value since last OCC reset + * @csm_min: Minimum value since last reset request + * by CSM (CORAL) + * @csm_max: Maximum value since last reset request + * by CSM (CORAL) + * @profiler_min: Minimum value since last reset request + * by profiler (CORAL) + * @profiler_max: Maximum value since last reset request + * by profiler (CORAL) + * @job_scheduler_min: Minimum value since last reset request + * by job scheduler(CORAL) + * @job_scheduler_max: Maximum value since last reset request + * by job scheduler (CORAL) + * @accumulator: Accumulator for this sensor + * @update_tag: Count of the number of ticks that have + * passed between updates + * @pad: Padding to fit the size of 48 bytes + */ +struct occ_sensor_record { + u16 gsid; + __be64 timestamp; + __be16 sample; + __be16 sample_min; + __be16 sample_max; + __be16 csm_min; + __be16 csm_max; + __be16 profiler_min; + __be16 profiler_max; + __be16 job_scheduler_min; + __be16 job_scheduler_max; + __be64 accumulator; + __be32 update_tag; + u8 pad[8]; +} __attribute__((__packed__)); + +/** + * struct occ_sensor_counter - Sensor Reading Counter + * @gsid: Global sensor id (OCC) + * @timestamp: Time base counter value while updating + * the sensor + * @accumulator: Accumulator/Counter + * @sample: Latest sample of this sensor (0/1) + * @pad: Padding to fit the size of 24 bytes + */ +struct occ_sensor_counter { + u16 gsid; + __be64 timestamp; + __be64 accumulator; + u8 sample; + u8 pad[5]; +} __attribute__((__packed__)); diff --git a/roms/skiboot/include/ocmb.h b/roms/skiboot/include/ocmb.h new file mode 100644 index 000000000..92212f33c --- /dev/null +++ b/roms/skiboot/include/ocmb.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Open Capi Memory Buffer chip + * + * Copyright 2020 IBM Corp. + */ + +#ifndef __OCMB_H +#define __OCMB_H + +extern void ocmb_init(void); + +#endif /* __OCMB_H */ diff --git a/roms/skiboot/include/op-panel.h b/roms/skiboot/include/op-panel.h new file mode 100644 index 000000000..7a4451285 --- /dev/null +++ b/roms/skiboot/include/op-panel.h @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __OP_PANEL_H +#define __OP_PANEL_H + +#include <stdint.h> + +/* Operator Panel Dimensions */ +#define OP_PANEL_NUM_LINES 2 +#define OP_PANEL_LINE_LEN 16 + +/* Severity */ +enum op_severity { + OP_LOG = 0x4342, /* 'CB' - Progress info */ + OP_WARN = 0x4542, /* 'EB' - Information condition */ + OP_ERROR = 0x4442, /* 'DB' - Non fatal error */ + OP_FATAL = 0x4242, /* 'BB' - Fatal error */ +}; + +/* Module */ +enum op_module { + OP_MOD_CORE = 0x3030, /* '00' - Anything really */ + OP_MOD_INIT = 0x3031, /* '01' - init */ + OP_MOD_LOCK = 0x3032, /* '02' - spinlocks */ + OP_MOD_FSP = 0x3033, /* '03' - FSP */ + OP_MOD_FSPCON = 0x3034, /* '04' - FSPCON */ + OP_MOD_CHIPTOD = 0x3035, /* '05' - ChipTOP */ + OP_MOD_CPU = 0x3036, /* '06' - CPU bringup */ + OP_MOD_MEM = 0x3037, /* '07' - Memory */ +}; + +/* Common codes: + * + * 'BA010001' : Failed to load a kernel + * 'BA010002' : Failed to create a device-tree + * 'BA020000' : Locking already owned lock + * 'BA020001' : Unlocking unlocked lock + * 'BA020002' : Unlocking not-owned lock + * 'BA006666' : Abort + * 'BA050000' : Failed ChipTOD init/sync + * 'BA050001' : Failed to find a CPU on the master chip + * 'BA050002' : Master chip sync failed + * 'EA05xxx2' : Slave sync failed (xxx = PIR) + * 'BA070000' : Cannot find MS VPD or invalid + * 'BA070001' : MS VPD wrong size + * 'BA070002' : MS VPD doesn't have an MSAC + * 'BA070003' : MS VPD doesn't have a total config + */ + +extern void op_display(enum op_severity, enum op_module, uint16_t code); +extern void op_display_lpc(enum op_severity s, enum op_module m, uint16_t c); + +extern void op_panel_disable_src_echo(void); +extern void op_panel_clear_src(void); +extern void fsp_oppanel_init(void); + +#endif /* __OP_PANEL_H */ diff --git a/roms/skiboot/include/opal-api.h b/roms/skiboot/include/opal-api.h new file mode 100644 index 000000000..348fda8c6 --- /dev/null +++ b/roms/skiboot/include/opal-api.h @@ -0,0 +1,1264 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __OPAL_API_H +#define __OPAL_API_H + +/****** OPAL APIs ******/ + +/* Return codes */ +#define OPAL_SUCCESS 0 +#define OPAL_PARAMETER -1 +#define OPAL_BUSY -2 +#define OPAL_PARTIAL -3 +#define OPAL_CONSTRAINED -4 +#define OPAL_CLOSED -5 +#define OPAL_HARDWARE -6 +#define OPAL_UNSUPPORTED -7 +#define OPAL_PERMISSION -8 +#define OPAL_NO_MEM -9 +#define OPAL_RESOURCE -10 +#define OPAL_INTERNAL_ERROR -11 +#define OPAL_BUSY_EVENT -12 +#define OPAL_HARDWARE_FROZEN -13 +#define OPAL_WRONG_STATE -14 +#define OPAL_ASYNC_COMPLETION -15 +#define OPAL_EMPTY -16 +#define OPAL_I2C_TIMEOUT -17 +#define OPAL_I2C_INVALID_CMD -18 +#define OPAL_I2C_LBUS_PARITY -19 +#define OPAL_I2C_BKEND_OVERRUN -20 +#define OPAL_I2C_BKEND_ACCESS -21 +#define OPAL_I2C_ARBT_LOST -22 +#define OPAL_I2C_NACK_RCVD -23 +#define OPAL_I2C_STOP_ERR -24 +#define OPAL_XSCOM_BUSY OPAL_BUSY +#define OPAL_XSCOM_CHIPLET_OFF OPAL_WRONG_STATE +#define OPAL_XSCOM_PARTIAL_GOOD -25 +#define OPAL_XSCOM_ADDR_ERROR -26 +#define OPAL_XSCOM_CLOCK_ERROR -27 +#define OPAL_XSCOM_PARITY_ERROR -28 +#define OPAL_XSCOM_TIMEOUT -29 +#define OPAL_XSCOM_CTR_OFFLINED -30 +#define OPAL_XIVE_PROVISIONING -31 +#define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 + +/* API Tokens (in r0) */ +#define OPAL_INVALID_CALL -1 +#define OPAL_TEST 0 +#define OPAL_CONSOLE_WRITE 1 +#define OPAL_CONSOLE_READ 2 +#define OPAL_RTC_READ 3 +#define OPAL_RTC_WRITE 4 +#define OPAL_CEC_POWER_DOWN 5 +#define OPAL_CEC_REBOOT 6 +#define OPAL_READ_NVRAM 7 +#define OPAL_WRITE_NVRAM 8 +#define OPAL_HANDLE_INTERRUPT 9 +#define OPAL_POLL_EVENTS 10 +#define OPAL_PCI_SET_HUB_TCE_MEMORY 11 /* Removed, p5ioc only */ +#define OPAL_PCI_SET_PHB_TCE_MEMORY 12 /* Removed, p5ioc only */ +#define OPAL_PCI_CONFIG_READ_BYTE 13 +#define OPAL_PCI_CONFIG_READ_HALF_WORD 14 +#define OPAL_PCI_CONFIG_READ_WORD 15 +#define OPAL_PCI_CONFIG_WRITE_BYTE 16 +#define OPAL_PCI_CONFIG_WRITE_HALF_WORD 17 +#define OPAL_PCI_CONFIG_WRITE_WORD 18 +#define OPAL_SET_XIVE 19 +#define OPAL_GET_XIVE 20 +#define OPAL_GET_COMPLETION_TOKEN_STATUS 21 /* obsolete */ +#define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER 22 +#define OPAL_PCI_EEH_FREEZE_STATUS 23 +#define OPAL_PCI_SHPC 24 +#define OPAL_CONSOLE_WRITE_BUFFER_SPACE 25 +#define OPAL_PCI_EEH_FREEZE_CLEAR 26 +#define OPAL_PCI_PHB_MMIO_ENABLE 27 +#define OPAL_PCI_SET_PHB_MEM_WINDOW 28 +#define OPAL_PCI_MAP_PE_MMIO_WINDOW 29 +#define OPAL_PCI_SET_PHB_TABLE_MEMORY 30 /* never implemented */ +#define OPAL_PCI_SET_PE 31 +#define OPAL_PCI_SET_PELTV 32 +#define OPAL_PCI_SET_MVE 33 +#define OPAL_PCI_SET_MVE_ENABLE 34 +#define OPAL_PCI_GET_XIVE_REISSUE 35 /* never implemented */ +#define OPAL_PCI_SET_XIVE_REISSUE 36 /* never implemented */ +#define OPAL_PCI_SET_XIVE_PE 37 +#define OPAL_GET_XIVE_SOURCE 38 +#define OPAL_GET_MSI_32 39 +#define OPAL_GET_MSI_64 40 +#define OPAL_START_CPU 41 +#define OPAL_QUERY_CPU_STATUS 42 +#define OPAL_WRITE_OPPANEL 43 /* unimplemented */ +#define OPAL_PCI_MAP_PE_DMA_WINDOW 44 +#define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL 45 +/* 46 is unused */ +/* 47 is unused */ +/* 48 is unused */ +#define OPAL_PCI_RESET 49 +#define OPAL_PCI_GET_HUB_DIAG_DATA 50 +#define OPAL_PCI_GET_PHB_DIAG_DATA 51 +#define OPAL_PCI_FENCE_PHB 52 +#define OPAL_PCI_REINIT 53 +#define OPAL_PCI_MASK_PE_ERROR 54 +#define OPAL_SET_SLOT_LED_STATUS 55 +#define OPAL_GET_EPOW_STATUS 56 +#define OPAL_SET_SYSTEM_ATTENTION_LED 57 +#define OPAL_RESERVED1 58 +#define OPAL_RESERVED2 59 +#define OPAL_PCI_NEXT_ERROR 60 +#define OPAL_PCI_EEH_FREEZE_STATUS2 61 +#define OPAL_PCI_POLL 62 +#define OPAL_PCI_MSI_EOI 63 +#define OPAL_PCI_GET_PHB_DIAG_DATA2 64 +#define OPAL_XSCOM_READ 65 +#define OPAL_XSCOM_WRITE 66 +#define OPAL_LPC_READ 67 +#define OPAL_LPC_WRITE 68 +#define OPAL_RETURN_CPU 69 +#define OPAL_REINIT_CPUS 70 +#define OPAL_ELOG_READ 71 +#define OPAL_ELOG_WRITE 72 +#define OPAL_ELOG_ACK 73 +#define OPAL_ELOG_RESEND 74 +#define OPAL_ELOG_SIZE 75 +#define OPAL_FLASH_VALIDATE 76 +#define OPAL_FLASH_MANAGE 77 +#define OPAL_FLASH_UPDATE 78 +#define OPAL_RESYNC_TIMEBASE 79 +#define OPAL_CHECK_TOKEN 80 +#define OPAL_DUMP_INIT 81 +#define OPAL_DUMP_INFO 82 +#define OPAL_DUMP_READ 83 +#define OPAL_DUMP_ACK 84 +#define OPAL_GET_MSG 85 +#define OPAL_CHECK_ASYNC_COMPLETION 86 +#define OPAL_SYNC_HOST_REBOOT 87 +#define OPAL_SENSOR_READ 88 +#define OPAL_GET_PARAM 89 +#define OPAL_SET_PARAM 90 +#define OPAL_DUMP_RESEND 91 +#define OPAL_ELOG_SEND 92 /* Deprecated */ +#define OPAL_PCI_SET_PHB_CAPI_MODE 93 +#define OPAL_DUMP_INFO2 94 +#define OPAL_WRITE_OPPANEL_ASYNC 95 +#define OPAL_PCI_ERR_INJECT 96 +#define OPAL_PCI_EEH_FREEZE_SET 97 +#define OPAL_HANDLE_HMI 98 +#define OPAL_CONFIG_CPU_IDLE_STATE 99 +#define OPAL_SLW_SET_REG 100 +#define OPAL_REGISTER_DUMP_REGION 101 +#define OPAL_UNREGISTER_DUMP_REGION 102 +#define OPAL_WRITE_TPO 103 +#define OPAL_READ_TPO 104 +#define OPAL_GET_DPO_STATUS 105 +#define OPAL_OLD_I2C_REQUEST 106 /* Deprecated */ +#define OPAL_IPMI_SEND 107 +#define OPAL_IPMI_RECV 108 +#define OPAL_I2C_REQUEST 109 +#define OPAL_FLASH_READ 110 +#define OPAL_FLASH_WRITE 111 +#define OPAL_FLASH_ERASE 112 +#define OPAL_PRD_MSG 113 +#define OPAL_LEDS_GET_INDICATOR 114 +#define OPAL_LEDS_SET_INDICATOR 115 +#define OPAL_CEC_REBOOT2 116 +#define OPAL_CONSOLE_FLUSH 117 +#define OPAL_GET_DEVICE_TREE 118 +#define OPAL_PCI_GET_PRESENCE_STATE 119 +#define OPAL_PCI_GET_POWER_STATE 120 +#define OPAL_PCI_SET_POWER_STATE 121 +#define OPAL_INT_GET_XIRR 122 +#define OPAL_INT_SET_CPPR 123 +#define OPAL_INT_EOI 124 +#define OPAL_INT_SET_MFRR 125 +#define OPAL_PCI_TCE_KILL 126 +#define OPAL_NMMU_SET_PTCR 127 +#define OPAL_XIVE_RESET 128 +#define OPAL_XIVE_GET_IRQ_INFO 129 +#define OPAL_XIVE_GET_IRQ_CONFIG 130 +#define OPAL_XIVE_SET_IRQ_CONFIG 131 +#define OPAL_XIVE_GET_QUEUE_INFO 132 +#define OPAL_XIVE_SET_QUEUE_INFO 133 +#define OPAL_XIVE_DONATE_PAGE 134 +#define OPAL_XIVE_ALLOCATE_VP_BLOCK 135 +#define OPAL_XIVE_FREE_VP_BLOCK 136 +#define OPAL_XIVE_GET_VP_INFO 137 +#define OPAL_XIVE_SET_VP_INFO 138 +#define OPAL_XIVE_ALLOCATE_IRQ 139 +#define OPAL_XIVE_FREE_IRQ 140 +#define OPAL_XIVE_SYNC 141 +#define OPAL_XIVE_DUMP 142 +#define OPAL_XIVE_GET_QUEUE_STATE 143 /* Get END state */ +#define OPAL_XIVE_SET_QUEUE_STATE 144 /* Set END state */ +#define OPAL_SIGNAL_SYSTEM_RESET 145 +#define OPAL_NPU_INIT_CONTEXT 146 +#define OPAL_NPU_DESTROY_CONTEXT 147 +#define OPAL_NPU_MAP_LPAR 148 +#define OPAL_IMC_COUNTERS_INIT 149 +#define OPAL_IMC_COUNTERS_START 150 +#define OPAL_IMC_COUNTERS_STOP 151 +#define OPAL_GET_POWERCAP 152 +#define OPAL_SET_POWERCAP 153 +#define OPAL_GET_POWER_SHIFT_RATIO 154 +#define OPAL_SET_POWER_SHIFT_RATIO 155 +#define OPAL_SENSOR_GROUP_CLEAR 156 +#define OPAL_PCI_SET_P2P 157 +#define OPAL_QUIESCE 158 +#define OPAL_NPU_SPA_SETUP 159 +#define OPAL_NPU_SPA_CLEAR_CACHE 160 +#define OPAL_NPU_TL_SET 161 +#define OPAL_SENSOR_READ_U64 162 +#define OPAL_SENSOR_GROUP_ENABLE 163 +#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164 +#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165 +#define OPAL_HANDLE_HMI2 166 +#define OPAL_NX_COPROC_INIT 167 +#define OPAL_NPU_SET_RELAXED_ORDER 168 +#define OPAL_NPU_GET_RELAXED_ORDER 169 +#define OPAL_XIVE_GET_VP_STATE 170 /* Get NVT state */ +#define OPAL_NPU_MEM_ALLOC 171 +#define OPAL_NPU_MEM_RELEASE 172 +#define OPAL_MPIPL_UPDATE 173 +#define OPAL_MPIPL_REGISTER_TAG 174 +#define OPAL_MPIPL_QUERY_TAG 175 +#define OPAL_SECVAR_GET 176 +#define OPAL_SECVAR_GET_NEXT 177 +#define OPAL_SECVAR_ENQUEUE_UPDATE 178 +#define OPAL_PHB_SET_OPTION 179 +#define OPAL_PHB_GET_OPTION 180 +#define OPAL_LAST 180 + +#define QUIESCE_HOLD 1 /* Spin all calls at entry */ +#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ +#define QUIESCE_LOCK_BREAK 3 /* Set to ignore locks. */ +#define QUIESCE_RESUME 4 /* Un-quiesce */ +#define QUIESCE_RESUME_FAST_REBOOT 5 /* Un-quiesce, fast reboot */ + +/* Device tree flags */ + +/* + * Flags set in power-mgmt nodes in device tree describing + * idle states that are supported in the platform. + */ +#define OPAL_PM_DEC_STOP 0x00000001 /* Decrementer would stop */ +#define OPAL_PM_TIMEBASE_STOP 0x00000002 /* Needs timebase restore */ +#define OPAL_PM_LOSE_USER_CONTEXT 0x00001000 /* Restore GPRs like nap */ +#define OPAL_PM_LOSE_HYP_CONTEXT 0x00002000 /* Restore hypervisor + resource from PACA pointer */ +#define OPAL_PM_LOSE_FULL_CONTEXT 0x00004000 +#define OPAL_PM_NAP_ENABLED 0x00010000 +#define OPAL_PM_SLEEP_ENABLED 0x00020000 +#define OPAL_PM_WINKLE_ENABLED 0x00040000 +#define OPAL_PM_SLEEP_ENABLED_ER1 0x00080000 /* with workaround */ +#define OPAL_USE_PMICR 0x00800000 /* Use SPR PMICR instruction */ + +#define OPAL_PM_FASTSLEEP_PMICR 0x0000002000000000UL +#define OPAL_PM_DEEPSLEEP_PMICR 0x0000003000000000UL +#define OPAL_PM_SLEEP_PMICR_MASK 0x0000003000000000UL + +#define OPAL_PM_FASTWINKLE_PMICR 0x0000000000200000UL +#define OPAL_PM_DEEPWINKLE_PMICR 0x0000000000300000UL +#define OPAL_PM_WINKLE_PMICR_MASK 0x0000000000300000UL + +#define OPAL_PM_PSSCR_RL_MASK 0x000000000000000FUL +#define OPAL_PM_PSSCR_MTL_MASK 0x00000000000000F0UL +#define OPAL_PM_PSSCR_TR_MASK 0x0000000000000300UL +#define OPAL_PM_PSSCR_ESL PPC_BIT(42) +#define OPAL_PM_PSSCR_EC PPC_BIT(43) + +#define OPAL_PM_PSSCR_MASK OPAL_PM_PSSCR_RL_MASK | \ + OPAL_PM_PSSCR_MTL_MASK | \ + OPAL_PM_PSSCR_TR_MASK | \ + OPAL_PM_PSSCR_ESL | \ + OPAL_PM_PSSCR_EC + +#define OPAL_PM_PSSCR_RL(l) (l) +#define OPAL_PM_PSSCR_MTL(l) ((l) << 4) +#define OPAL_PM_PSSCR_TR(l) ((l) << 8) + +/* + * Flags for stop states. Use 2 bits to distinguish between + * deep and fast states. Deep states result in full context + * loss thereby requiring slw to partially restore state + * whereas fast state can function without the presence of + * slw. + */ +#define OPAL_PM_STOP_INST_FAST 0x00100000 +#define OPAL_PM_STOP_INST_DEEP 0x00200000 + +#ifndef __ASSEMBLY__ + +#include <stdbool.h> +#include <types.h> + +/* Other enums */ +enum OpalVendorApiTokens { + OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999 +}; + +enum OpalFreezeState { + OPAL_EEH_STOPPED_NOT_FROZEN = 0, + OPAL_EEH_STOPPED_MMIO_FREEZE = 1, + OPAL_EEH_STOPPED_DMA_FREEZE = 2, + OPAL_EEH_STOPPED_MMIO_DMA_FREEZE = 3, + OPAL_EEH_STOPPED_RESET = 4, + OPAL_EEH_STOPPED_TEMP_UNAVAIL = 5, + OPAL_EEH_STOPPED_PERM_UNAVAIL = 6 +}; + +enum OpalEehFreezeActionToken { + OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1, + OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3, + + OPAL_EEH_ACTION_SET_FREEZE_MMIO = 1, + OPAL_EEH_ACTION_SET_FREEZE_DMA = 2, + OPAL_EEH_ACTION_SET_FREEZE_ALL = 3 +}; + +enum OpalPciStatusToken { + OPAL_EEH_NO_ERROR = 0, + OPAL_EEH_IOC_ERROR = 1, + OPAL_EEH_PHB_ERROR = 2, + OPAL_EEH_PE_ERROR = 3, + OPAL_EEH_PE_MMIO_ERROR = 4, + OPAL_EEH_PE_DMA_ERROR = 5 +}; + +enum OpalPciErrorSeverity { + OPAL_EEH_SEV_NO_ERROR = 0, + OPAL_EEH_SEV_IOC_DEAD = 1, + OPAL_EEH_SEV_PHB_DEAD = 2, + OPAL_EEH_SEV_PHB_FENCED = 3, + OPAL_EEH_SEV_PE_ER = 4, + OPAL_EEH_SEV_INF = 5 +}; + +enum OpalErrinjectType { + OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR = 0, + OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64 = 1, +}; + +enum OpalErrinjectFunc { + /* IOA bus specific errors */ + OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR = 0, + OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_DATA = 1, + OPAL_ERR_INJECT_FUNC_IOA_LD_IO_ADDR = 2, + OPAL_ERR_INJECT_FUNC_IOA_LD_IO_DATA = 3, + OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_ADDR = 4, + OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_DATA = 5, + OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_ADDR = 6, + OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_DATA = 7, + OPAL_ERR_INJECT_FUNC_IOA_ST_IO_ADDR = 8, + OPAL_ERR_INJECT_FUNC_IOA_ST_IO_DATA = 9, + OPAL_ERR_INJECT_FUNC_IOA_ST_CFG_ADDR = 10, + OPAL_ERR_INJECT_FUNC_IOA_ST_CFG_DATA = 11, + OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_ADDR = 12, + OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_DATA = 13, + OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_MASTER = 14, + OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_TARGET = 15, + OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_ADDR = 16, + OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_DATA = 17, + OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_MASTER = 18, + OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_TARGET = 19, +}; + +enum OpalShpcAction { + OPAL_SHPC_GET_LINK_STATE = 0, + OPAL_SHPC_GET_SLOT_STATE = 1 +}; + +enum OpalShpcLinkState { + OPAL_SHPC_LINK_DOWN = 0, + OPAL_SHPC_LINK_UP_x1 = 1, + OPAL_SHPC_LINK_UP_x2 = 2, + OPAL_SHPC_LINK_UP_x4 = 4, + OPAL_SHPC_LINK_UP_x8 = 8, + OPAL_SHPC_LINK_UP_x16 = 16, + OPAL_SHPC_LINK_UP_x32 = 32 +}; + +enum OpalMmioWindowType { + OPAL_M32_WINDOW_TYPE = 1, + OPAL_M64_WINDOW_TYPE = 2, + OPAL_IO_WINDOW_TYPE = 3 +}; + +enum OpalShpcSlotState { + OPAL_SHPC_DEV_NOT_PRESENT = 0, + OPAL_SHPC_DEV_PRESENT = 1 +}; +enum OpalShpcPowerState { + OPAL_SHPC_POWER_OFF = 0, + OPAL_SHPC_POWER_ON = 1 +}; + +enum OpalExceptionHandler { + OPAL_MACHINE_CHECK_HANDLER = 1, + OPAL_HYPERVISOR_MAINTENANCE_HANDLER = 2, + OPAL_SOFTPATCH_HANDLER = 3 +}; + +enum OpalPendingState { + OPAL_EVENT_OPAL_INTERNAL = 0x1, + OPAL_EVENT_NVRAM = 0x2, + OPAL_EVENT_RTC = 0x4, + OPAL_EVENT_CONSOLE_OUTPUT = 0x8, + OPAL_EVENT_CONSOLE_INPUT = 0x10, + OPAL_EVENT_ERROR_LOG_AVAIL = 0x20, + OPAL_EVENT_ERROR_LOG = 0x40, + OPAL_EVENT_EPOW = 0x80, + OPAL_EVENT_LED_STATUS = 0x100, + OPAL_EVENT_PCI_ERROR = 0x200, + OPAL_EVENT_DUMP_AVAIL = 0x400, + OPAL_EVENT_MSG_PENDING = 0x800, +}; + +enum OpalThreadStatus { + OPAL_THREAD_INACTIVE = 0x0, + OPAL_THREAD_STARTED = 0x1, + OPAL_THREAD_UNAVAILABLE = 0x2 /* opal-v3 */ +}; + +enum OpalPciBusCompare { + OpalPciBusAny = 0, /* Any bus number match */ + OpalPciBus3Bits = 2, /* Match top 3 bits of bus number */ + OpalPciBus4Bits = 3, /* Match top 4 bits of bus number */ + OpalPciBus5Bits = 4, /* Match top 5 bits of bus number */ + OpalPciBus6Bits = 5, /* Match top 6 bits of bus number */ + OpalPciBus7Bits = 6, /* Match top 7 bits of bus number */ + OpalPciBusAll = 7, /* Match bus number exactly */ +}; + +enum OpalDeviceCompare { + OPAL_IGNORE_RID_DEVICE_NUMBER = 0, + OPAL_COMPARE_RID_DEVICE_NUMBER = 1 +}; + +enum OpalFuncCompare { + OPAL_IGNORE_RID_FUNCTION_NUMBER = 0, + OPAL_COMPARE_RID_FUNCTION_NUMBER = 1 +}; + +enum OpalPeAction { + OPAL_UNMAP_PE = 0, + OPAL_MAP_PE = 1 +}; + +enum OpalPeltvAction { + OPAL_REMOVE_PE_FROM_DOMAIN = 0, + OPAL_ADD_PE_TO_DOMAIN = 1 +}; + +enum OpalMveEnableAction { + OPAL_DISABLE_MVE = 0, + OPAL_ENABLE_MVE = 1 +}; + +enum OpalM64Action { + OPAL_DISABLE_M64 = 0, + OPAL_ENABLE_M64_SPLIT = 1, + OPAL_ENABLE_M64_NON_SPLIT = 2 +}; + +enum OpalPciResetScope { + OPAL_RESET_PHB_COMPLETE = 1, + OPAL_RESET_PCI_LINK = 2, + OPAL_RESET_PHB_ERROR = 3, + OPAL_RESET_PCI_HOT = 4, + OPAL_RESET_PCI_FUNDAMENTAL = 5, + OPAL_RESET_PCI_IODA_TABLE = 6 +}; + +enum OpalPciReinitScope { + /* + * Note: we chose values that do not overlap + * OpalPciResetScope as OPAL v2 used the same + * enum for both + */ + OPAL_REINIT_PCI_DEV = 1000 +}; + +enum OpalPciResetState { + OPAL_DEASSERT_RESET = 0, + OPAL_ASSERT_RESET = 1 +}; + +enum OpalPciMaskAction { + OPAL_UNMASK_ERROR_TYPE = 0, + OPAL_MASK_ERROR_TYPE = 1 +}; + +enum OpalPciSlotPresence { + OPAL_PCI_SLOT_EMPTY = 0, + OPAL_PCI_SLOT_PRESENT = 1 +}; + +enum OpalPciSlotPower { + OPAL_PCI_SLOT_POWER_OFF = 0, + OPAL_PCI_SLOT_POWER_ON = 1, + OPAL_PCI_SLOT_OFFLINE = 2, + OPAL_PCI_SLOT_ONLINE = 3 +}; + +enum OpalSlotLedType { + OPAL_SLOT_LED_TYPE_ID = 0, /* IDENTIFY LED */ + OPAL_SLOT_LED_TYPE_FAULT = 1, /* FAULT LED */ + OPAL_SLOT_LED_TYPE_ATTN = 2, /* System Attention LED */ + OPAL_SLOT_LED_TYPE_MAX = 3 +}; + +enum OpalSlotLedState { + OPAL_SLOT_LED_STATE_OFF = 0, /* LED is OFF */ + OPAL_SLOT_LED_STATE_ON = 1 /* LED is ON */ +}; + +enum OpalEpowStatus { + OPAL_EPOW_NONE = 0, + OPAL_EPOW_UPS = 1, + OPAL_EPOW_OVER_AMBIENT_TEMP = 2, + OPAL_EPOW_OVER_INTERNAL_TEMP = 3 +}; + +enum OpalCheckTokenStatus { + OPAL_TOKEN_ABSENT = 0, + OPAL_TOKEN_PRESENT = 1 +}; + +enum OpalPhbOption { + OPAL_PHB_OPTION_TVE1_4GB = 0x1, + OPAL_PHB_OPTION_MMIO_EEH_DISABLE = 0x2, +}; + +/* + * Address cycle types for LPC accesses. These also correspond + * to the content of the first cell of the "reg" property for + * device nodes on the LPC bus + */ +enum OpalLPCAddressType { + OPAL_LPC_MEM = 0, + OPAL_LPC_IO = 1, + OPAL_LPC_FW = 2, +}; + +enum opal_msg_type { + OPAL_MSG_ASYNC_COMP = 0, /* params[0] = token, params[1] = rc, + * additional params function-specific + */ + OPAL_MSG_MEM_ERR = 1, + OPAL_MSG_EPOW = 2, + OPAL_MSG_SHUTDOWN = 3, /* params[0] = 1 reboot, 0 shutdown */ + OPAL_MSG_HMI_EVT = 4, + OPAL_MSG_DPO = 5, + OPAL_MSG_PRD = 6, + OPAL_MSG_OCC = 7, + OPAL_MSG_PRD2 = 8, + OPAL_MSG_TYPE_MAX, +}; + +struct opal_msg { + __be32 msg_type; + __be32 size; + __be64 params[8]; +}; + +/* System parameter permission */ +enum OpalSysparamPerm { + OPAL_SYSPARAM_READ = 0x1, + OPAL_SYSPARAM_WRITE = 0x2, + OPAL_SYSPARAM_RW = (OPAL_SYSPARAM_READ | OPAL_SYSPARAM_WRITE), +}; + +enum { + OPAL_IPMI_MSG_FORMAT_VERSION_1 = 1, +}; + +struct opal_ipmi_msg { + uint8_t version; + uint8_t netfn; + uint8_t cmd; + uint8_t data[]; +}; + +/* + * EPOW status sharing (OPAL and the host) + * + * The host will pass on OPAL, a buffer of length OPAL_SYSEPOW_MAX + * with individual elements being 16 bits wide to fetch the system + * wide EPOW status. Each element in the buffer will contain the + * EPOW status in it's bit representation for a particular EPOW sub + * class as defined here. So multiple detailed EPOW status bits + * specific for any sub class can be represented in a single buffer + * element as it's bit representation. + */ + +/* System EPOW type */ +enum OpalSysEpow { + OPAL_SYSEPOW_POWER = 0, /* Power EPOW */ + OPAL_SYSEPOW_TEMP = 1, /* Temperature EPOW */ + OPAL_SYSEPOW_COOLING = 2, /* Cooling EPOW */ + OPAL_SYSEPOW_MAX = 3, /* Max EPOW categories */ +}; + +/* Power EPOW */ +enum OpalSysPower { + OPAL_SYSPOWER_UPS = 0x0001, /* System on UPS power */ + OPAL_SYSPOWER_CHNG = 0x0002, /* System power configuration change */ + OPAL_SYSPOWER_FAIL = 0x0004, /* System impending power failure */ + OPAL_SYSPOWER_INCL = 0x0008, /* System incomplete power */ +}; + +/* Temperature EPOW */ +enum OpalSysTemp { + OPAL_SYSTEMP_AMB = 0x0001, /* System over ambient temperature */ + OPAL_SYSTEMP_INT = 0x0002, /* System over internal temperature */ + OPAL_SYSTEMP_HMD = 0x0004, /* System over ambient humidity */ +}; + +/* Cooling EPOW */ +enum OpalSysCooling { + OPAL_SYSCOOL_INSF = 0x0001, /* System insufficient cooling */ +}; + +/* FSP memory errors handling */ +enum OpalMemErr_Version { + OpalMemErr_V1 = 1, +}; + +enum OpalMemErrType { + OPAL_MEM_ERR_TYPE_RESILIENCE = 0, + OPAL_MEM_ERR_TYPE_DYN_DALLOC, +}; + +/* Memory Reilience error type */ +enum OpalMemErr_ResilErrType { + OPAL_MEM_RESILIENCE_CE = 0, + OPAL_MEM_RESILIENCE_UE, + OPAL_MEM_RESILIENCE_UE_SCRUB, +}; + +/* Dynamic Memory Deallocation type */ +enum OpalMemErr_DynErrType { + OPAL_MEM_DYNAMIC_DEALLOC = 0, +}; + +/* OpalMemoryErrorData->flags */ +#define OPAL_MEM_CORRECTED_ERROR 0x0001 +#define OPAL_MEM_THRESHOLD_EXCEEDED 0x0002 +#define OPAL_MEM_ACK_REQUIRED 0x8000 + +struct OpalMemoryErrorData { + enum OpalMemErr_Version version:8; /* 0x00 */ + enum OpalMemErrType type:8; /* 0x01 */ + __be16 flags; /* 0x02 */ + uint8_t reserved_1[4]; /* 0x04 */ + + union { + /* Memory Resilience corrected/uncorrected error info */ + struct { + enum OpalMemErr_ResilErrType resil_err_type:8; + uint8_t reserved_1[7]; + __be64 physical_address_start; + __be64 physical_address_end; + } resilience; + /* Dynamic memory deallocation error info */ + struct { + enum OpalMemErr_DynErrType dyn_err_type:8; + uint8_t reserved_1[7]; + __be64 physical_address_start; + __be64 physical_address_end; + } dyn_dealloc; + } u; +}; + +/* HMI interrupt event */ +enum OpalHMI_Version { + OpalHMIEvt_V1 = 1, + OpalHMIEvt_V2 = 2, +}; + +enum OpalHMI_Severity { + OpalHMI_SEV_NO_ERROR = 0, + OpalHMI_SEV_WARNING = 1, + OpalHMI_SEV_ERROR_SYNC = 2, + OpalHMI_SEV_FATAL = 3, +}; + +enum OpalHMI_Disposition { + OpalHMI_DISPOSITION_RECOVERED = 0, + OpalHMI_DISPOSITION_NOT_RECOVERED = 1, +}; + +enum OpalHMI_ErrType { + OpalHMI_ERROR_MALFUNC_ALERT = 0, + OpalHMI_ERROR_PROC_RECOV_DONE, + OpalHMI_ERROR_PROC_RECOV_DONE_AGAIN, + OpalHMI_ERROR_PROC_RECOV_MASKED, + OpalHMI_ERROR_TFAC, + OpalHMI_ERROR_TFMR_PARITY, + OpalHMI_ERROR_HA_OVERFLOW_WARN, + OpalHMI_ERROR_XSCOM_FAIL, + OpalHMI_ERROR_XSCOM_DONE, + OpalHMI_ERROR_SCOM_FIR, + OpalHMI_ERROR_DEBUG_TRIG_FIR, + OpalHMI_ERROR_HYP_RESOURCE, + OpalHMI_ERROR_CAPP_RECOVERY, +}; + +enum OpalHMI_XstopType { + CHECKSTOP_TYPE_UNKNOWN = 0, + CHECKSTOP_TYPE_CORE = 1, + CHECKSTOP_TYPE_NX = 2, + CHECKSTOP_TYPE_NPU = 3 +}; + +enum OpalHMI_CoreXstopReason { + CORE_CHECKSTOP_IFU_REGFILE = 0x00000001, + CORE_CHECKSTOP_IFU_LOGIC = 0x00000002, + CORE_CHECKSTOP_PC_DURING_RECOV = 0x00000004, + CORE_CHECKSTOP_ISU_REGFILE = 0x00000008, + CORE_CHECKSTOP_ISU_LOGIC = 0x00000010, + CORE_CHECKSTOP_FXU_LOGIC = 0x00000020, + CORE_CHECKSTOP_VSU_LOGIC = 0x00000040, + CORE_CHECKSTOP_PC_RECOV_IN_MAINT_MODE = 0x00000080, + CORE_CHECKSTOP_LSU_REGFILE = 0x00000100, + CORE_CHECKSTOP_PC_FWD_PROGRESS = 0x00000200, + CORE_CHECKSTOP_LSU_LOGIC = 0x00000400, + CORE_CHECKSTOP_PC_LOGIC = 0x00000800, + CORE_CHECKSTOP_PC_HYP_RESOURCE = 0x00001000, + CORE_CHECKSTOP_PC_HANG_RECOV_FAILED = 0x00002000, + CORE_CHECKSTOP_PC_AMBI_HANG_DETECTED = 0x00004000, + CORE_CHECKSTOP_PC_DEBUG_TRIG_ERR_INJ = 0x00008000, + CORE_CHECKSTOP_PC_SPRD_HYP_ERR_INJ = 0x00010000, + CORE_CHECKSTOP_MMU_SYSTEM = 0x00020000, +}; + +enum OpalHMI_NestAccelXstopReason { + NX_CHECKSTOP_SHM_INVAL_STATE_ERR = 0x00000001, + NX_CHECKSTOP_DMA_INVAL_STATE_ERR_1 = 0x00000002, + NX_CHECKSTOP_DMA_INVAL_STATE_ERR_2 = 0x00000004, + NX_CHECKSTOP_DMA_CH0_INVAL_STATE_ERR = 0x00000008, + NX_CHECKSTOP_DMA_CH1_INVAL_STATE_ERR = 0x00000010, + NX_CHECKSTOP_DMA_CH2_INVAL_STATE_ERR = 0x00000020, + NX_CHECKSTOP_DMA_CH3_INVAL_STATE_ERR = 0x00000040, + NX_CHECKSTOP_DMA_CH4_INVAL_STATE_ERR = 0x00000080, + NX_CHECKSTOP_DMA_CH5_INVAL_STATE_ERR = 0x00000100, + NX_CHECKSTOP_DMA_CH6_INVAL_STATE_ERR = 0x00000200, + NX_CHECKSTOP_DMA_CH7_INVAL_STATE_ERR = 0x00000400, + NX_CHECKSTOP_DMA_CRB_UE = 0x00000800, + NX_CHECKSTOP_DMA_CRB_SUE = 0x00001000, + NX_CHECKSTOP_PBI_ISN_UE = 0x00002000, +}; + +struct OpalHMIEvent { + uint8_t version; /* 0x00 */ + uint8_t severity; /* 0x01 */ + uint8_t type; /* 0x02 */ + uint8_t disposition; /* 0x03 */ + uint8_t reserved_1[4]; /* 0x04 */ + + __be64 hmer; + /* TFMR register. Valid only for TFAC and TFMR_PARITY error type. */ + __be64 tfmr; + + /* version 2 and later */ + union { + /* + * checkstop info (Core/NX). + * Valid for OpalHMI_ERROR_MALFUNC_ALERT. + */ + struct { + uint8_t xstop_type; /* enum OpalHMI_XstopType */ + uint8_t reserved_1[3]; + __be32 xstop_reason; + union { + __be32 pir; /* for CHECKSTOP_TYPE_CORE */ + __be32 chip_id; /* for CHECKSTOP_TYPE_NX */ + } u; + } xstop_error; + } u; +}; + +/* OPAL_HANDLE_HMI2 out_flags */ +enum { + OPAL_HMI_FLAGS_TB_RESYNC = (1ull << 0), /* Timebase has been resynced */ + OPAL_HMI_FLAGS_DEC_LOST = (1ull << 1), /* DEC lost, needs to be reprogrammed */ + OPAL_HMI_FLAGS_HDEC_LOST = (1ull << 2), /* HDEC lost, needs to be reprogrammed */ + OPAL_HMI_FLAGS_TOD_TB_FAIL = (1ull << 3), /* TOD/TB recovery failed. */ + OPAL_HMI_FLAGS_NEW_EVENT = (1ull << 63), /* An event has been created */ +}; + +/** + * This structure defines the overlay which will be used to store PHB error + * data upon request. + */ +enum { + OPAL_PHB_ERROR_DATA_VERSION_1 = 1, +}; + +enum { + OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2, + OPAL_PHB_ERROR_DATA_TYPE_PHB4 = 3, + OPAL_PHB_ERROR_DATA_TYPE_PHB5 = 3 /* TODO change this */ +}; + +enum { + OPAL_PHB3_NUM_PEST_REGS = 256, + OPAL_PHB4_NUM_PEST_REGS = 512 +}; + +struct OpalIoPhbErrorCommon { + __be32 version; + __be32 ioType; + __be32 len; +}; + +struct OpalIoPhb3ErrorData { + struct OpalIoPhbErrorCommon common; + + __be32 brdgCtl; + + /* PHB3 UTL regs */ + __be32 portStatusReg; + __be32 rootCmplxStatus; + __be32 busAgentStatus; + + /* PHB3 cfg regs */ + __be32 deviceStatus; + __be32 slotStatus; + __be32 linkStatus; + __be32 devCmdStatus; + __be32 devSecStatus; + + /* cfg AER regs */ + __be32 rootErrorStatus; + __be32 uncorrErrorStatus; + __be32 corrErrorStatus; + __be32 tlpHdr1; + __be32 tlpHdr2; + __be32 tlpHdr3; + __be32 tlpHdr4; + __be32 sourceId; + + __be32 rsv3; + + /* Record data about the call to allocate a buffer */ + __be64 errorClass; + __be64 correlator; + + /* PHB3 MMIO Error Regs */ + __be64 nFir; /* 000 */ + __be64 nFirMask; /* 003 */ + __be64 nFirWOF; /* 008 */ + __be64 phbPlssr; /* 120 */ + __be64 phbCsr; /* 110 */ + __be64 lemFir; /* C00 */ + __be64 lemErrorMask; /* C18 */ + __be64 lemWOF; /* C40 */ + __be64 phbErrorStatus; /* C80 */ + __be64 phbFirstErrorStatus; /* C88 */ + __be64 phbErrorLog0; /* CC0 */ + __be64 phbErrorLog1; /* CC8 */ + __be64 mmioErrorStatus; /* D00 */ + __be64 mmioFirstErrorStatus; /* D08 */ + __be64 mmioErrorLog0; /* D40 */ + __be64 mmioErrorLog1; /* D48 */ + __be64 dma0ErrorStatus; /* D80 */ + __be64 dma0FirstErrorStatus; /* D88 */ + __be64 dma0ErrorLog0; /* DC0 */ + __be64 dma0ErrorLog1; /* DC8 */ + __be64 dma1ErrorStatus; /* E00 */ + __be64 dma1FirstErrorStatus; /* E08 */ + __be64 dma1ErrorLog0; /* E40 */ + __be64 dma1ErrorLog1; /* E48 */ + __be64 pestA[OPAL_PHB3_NUM_PEST_REGS]; + __be64 pestB[OPAL_PHB3_NUM_PEST_REGS]; +}; + +struct OpalIoPhb4ErrorData { + struct OpalIoPhbErrorCommon common; + + __be32 brdgCtl; + + /* XXX missing UTL registers? */ + + /* PHB4 cfg regs */ + __be32 deviceStatus; + __be32 slotStatus; + __be32 linkStatus; + __be32 devCmdStatus; + __be32 devSecStatus; + + /* cfg AER regs */ + __be32 rootErrorStatus; + __be32 uncorrErrorStatus; + __be32 corrErrorStatus; + __be32 tlpHdr1; + __be32 tlpHdr2; + __be32 tlpHdr3; + __be32 tlpHdr4; + __be32 sourceId; + + /* PHB4 ETU Error Regs */ + __be64 nFir; /* 000 */ + __be64 nFirMask; /* 003 */ + __be64 nFirWOF; /* 008 */ + __be64 phbPlssr; /* 120 */ + __be64 phbCsr; /* 110 */ + __be64 lemFir; /* C00 */ + __be64 lemErrorMask; /* C18 */ + __be64 lemWOF; /* C40 */ + __be64 phbErrorStatus; /* C80 */ + __be64 phbFirstErrorStatus; /* C88 */ + __be64 phbErrorLog0; /* CC0 */ + __be64 phbErrorLog1; /* CC8 */ + __be64 phbTxeErrorStatus; /* D00 */ + __be64 phbTxeFirstErrorStatus; /* D08 */ + __be64 phbTxeErrorLog0; /* D40 */ + __be64 phbTxeErrorLog1; /* D48 */ + __be64 phbRxeArbErrorStatus; /* D80 */ + __be64 phbRxeArbFirstErrorStatus; /* D88 */ + __be64 phbRxeArbErrorLog0; /* DC0 */ + __be64 phbRxeArbErrorLog1; /* DC8 */ + __be64 phbRxeMrgErrorStatus; /* E00 */ + __be64 phbRxeMrgFirstErrorStatus; /* E08 */ + __be64 phbRxeMrgErrorLog0; /* E40 */ + __be64 phbRxeMrgErrorLog1; /* E48 */ + __be64 phbRxeTceErrorStatus; /* E80 */ + __be64 phbRxeTceFirstErrorStatus; /* E88 */ + __be64 phbRxeTceErrorLog0; /* EC0 */ + __be64 phbRxeTceErrorLog1; /* EC8 */ + + /* PHB4 REGB Error Regs */ + __be64 phbPblErrorStatus; /* 1900 */ + __be64 phbPblFirstErrorStatus; /* 1908 */ + __be64 phbPblErrorLog0; /* 1940 */ + __be64 phbPblErrorLog1; /* 1948 */ + __be64 phbPcieDlpErrorLog1; /* 1AA0 */ + __be64 phbPcieDlpErrorLog2; /* 1AA8 */ + __be64 phbPcieDlpErrorStatus; /* 1AB0 */ + __be64 phbRegbErrorStatus; /* 1C00 */ + __be64 phbRegbFirstErrorStatus; /* 1C08 */ + __be64 phbRegbErrorLog0; /* 1C40 */ + __be64 phbRegbErrorLog1; /* 1C48 */ + + __be64 pestA[OPAL_PHB4_NUM_PEST_REGS]; + __be64 pestB[OPAL_PHB4_NUM_PEST_REGS]; +}; + +enum { + OPAL_REINIT_CPUS_HILE_BE = (1 << 0), + OPAL_REINIT_CPUS_HILE_LE = (1 << 1), + + /* These two define the base MMU mode of the host on P9 + * + * On P9 Nimbus DD2.0 and Cumlus (and later), KVM can still + * create hash guests in "radix" mode with care (full core + * switch only). + */ + OPAL_REINIT_CPUS_MMU_HASH = (1 << 2), + OPAL_REINIT_CPUS_MMU_RADIX = (1 << 3), + + OPAL_REINIT_CPUS_TM_SUSPEND_DISABLED = (1 << 4), +}; + +typedef struct oppanel_line { + __be64 line; + __be64 line_len; +} oppanel_line_t; + +enum opal_prd_msg_type { + OPAL_PRD_MSG_TYPE_INIT = 0, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_FINI, /* HBRT/kernel --> OPAL */ + OPAL_PRD_MSG_TYPE_ATTN, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_ATTN_ACK, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_OCC_ERROR, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_OCC_RESET, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_FIRMWARE_REQUEST, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_FIRMWARE_RESPONSE, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_FSP_OCC_RESET, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_STATUS, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS, /* HBRT --> OPAL */ +}; + +#define OPAL_PRD_MSG_SIZE_MAX (1 << 16) + +struct opal_prd_msg_header { + uint8_t type; + uint8_t pad[1]; + __be16 size; +}; + +struct opal_prd_msg { + struct opal_prd_msg_header hdr; + __be32 token; + union { + struct { + __be64 version; + __be64 ipoll; + } init; + struct { + __be64 proc; + __be64 ipoll_status; + __be64 ipoll_mask; + } attn; + struct { + __be64 proc; + __be64 ipoll_ack; + } attn_ack; + struct { + __be64 chip; + } occ_error; + struct { + __be64 chip; + } occ_reset; + struct { + __be64 req_len; + __be64 resp_len; + char data[]; + } fw_req; + struct { + __be64 len; + char data[]; + } fw_resp; + struct { + __be64 len; + char data[]; + } fw_notify; + struct { + __be64 chip; + } sbe_passthrough; + struct { + __be64 chip; + __be64 status; /* 0 SUCCESS */ + } fsp_occ_reset_status; + struct { + __be32 core; + __be32 mode; + } spl_wakeup; + }; +}; + +#define OCC_RESET 0 +#define OCC_LOAD 1 +#define OCC_THROTTLE 2 +#define OCC_MAX_THROTTLE_STATUS 5 +/* + * struct opal_occ_msg: + * type: OCC_RESET, OCC_LOAD, OCC_THROTTLE + * chip: chip id + * throttle status: indicates the reason why OCC may have limited + * the max Pstate of the chip. + * 0x00 = No throttle + * 0x01 = Power Cap + * 0x02 = Processor Over Temperature + * 0x03 = Power Supply Failure (currently not used) + * 0x04 = Over current (currently not used) + * 0x05 = OCC Reset (not reliable as some failures will not allow for + * OCC to update throttle status) + */ +struct opal_occ_msg { + __be64 type; + __be64 chip; + __be64 throttle_status; +}; + +/* + * SG entries + * + * WARNING: The current implementation requires each entry + * to represent a block that is 4k aligned *and* each block + * size except the last one in the list to be as well. + */ +struct opal_sg_entry { + __be64 data; + __be64 length; +}; + +/* + * Candidate image SG list. + * + * length = VER | length + */ +struct opal_sg_list { + __be64 length; + __be64 next; + struct opal_sg_entry entry[]; +}; + +/* + * Dump region ID range usable by the OS + */ +#define OPAL_DUMP_REGION_HOST_START 0x80 +#define OPAL_DUMP_REGION_LOG_BUF 0x80 +#define OPAL_DUMP_REGION_HOST_END 0xFF + +/* CAPI modes for PHB */ +enum { + OPAL_PHB_CAPI_MODE_PCIE = 0, + OPAL_PHB_CAPI_MODE_CAPI = 1, + OPAL_PHB_CAPI_MODE_SNOOP_OFF = 2, + OPAL_PHB_CAPI_MODE_SNOOP_ON = 3, + OPAL_PHB_CAPI_MODE_DMA = 4, + OPAL_PHB_CAPI_MODE_DMA_TVT1 = 5, +}; + +/* CAPI feature flags (in device-tree) */ +#define OPAL_PHB_CAPI_FLAG_SNOOP_CONTROL 0x00000001 +#define OPAL_PHB_CAPI_FLAG_REVERT_TO_PCIE 0x00000002 + +/* OPAL I2C request */ +struct opal_i2c_request { + uint8_t type; +#define OPAL_I2C_RAW_READ 0 +#define OPAL_I2C_RAW_WRITE 1 +#define OPAL_I2C_SM_READ 2 +#define OPAL_I2C_SM_WRITE 3 + uint8_t flags; +#define OPAL_I2C_ADDR_10 0x01 /* Not supported yet */ + uint8_t subaddr_sz; /* Max 4 */ + uint8_t reserved; + __be16 addr; /* 7 or 10 bit address */ + __be16 reserved2; + __be32 subaddr; /* Sub-address if any */ + __be32 size; /* Data size */ + __be64 buffer_ra; /* Buffer real address */ +}; + +/* Argument to OPAL_CEC_REBOOT2() */ +enum { + OPAL_REBOOT_NORMAL = 0, + OPAL_REBOOT_PLATFORM_ERROR, + OPAL_REBOOT_FULL_IPL, + OPAL_REBOOT_MPIPL, + OPAL_REBOOT_FAST, +}; + +/* Argument to OPAL_PCI_TCE_KILL */ +enum { + OPAL_PCI_TCE_KILL_PAGES, + OPAL_PCI_TCE_KILL_PE, + OPAL_PCI_TCE_KILL_ALL, +}; + +/* The xive operation mode indicates the active "API" and + * corresponds to the "mode" parameter of the opal_xive_reset() + * call + */ +enum { + OPAL_XIVE_MODE_EMU = 0, + OPAL_XIVE_MODE_EXPL = 1, +}; + +/* Flags for OPAL_XIVE_GET_IRQ_INFO */ +enum { + OPAL_XIVE_IRQ_TRIGGER_PAGE = 0x00000001, + OPAL_XIVE_IRQ_STORE_EOI = 0x00000002, + OPAL_XIVE_IRQ_LSI = 0x00000004, + OPAL_XIVE_IRQ_SHIFT_BUG = 0x00000008, /* DD1.0 workaround */ + OPAL_XIVE_IRQ_MASK_VIA_FW = 0x00000010, /* DD1.0 workaround */ + OPAL_XIVE_IRQ_EOI_VIA_FW = 0x00000020, /* DD1.0 workaround */ + OPAL_XIVE_IRQ_STORE_EOI2 = 0x00000040, +}; + +/* Flags for OPAL_XIVE_GET/SET_QUEUE_INFO */ +enum { + OPAL_XIVE_EQ_ENABLED = 0x00000001, + OPAL_XIVE_EQ_ALWAYS_NOTIFY = 0x00000002, + OPAL_XIVE_EQ_ESCALATE = 0x00000004, +}; + +/* Flags for OPAL_XIVE_GET/SET_VP_INFO */ +enum { + OPAL_XIVE_VP_ENABLED = 0x00000001, + OPAL_XIVE_VP_SINGLE_ESCALATION = 0x00000002, + OPAL_XIVE_VP_SAVE_RESTORE = 0x00000004, +}; + +/* "Any chip" replacement for chip ID for allocation functions */ +enum { + OPAL_XIVE_ANY_CHIP = 0xffffffff, +}; + +/* Xive sync options */ +enum { + /* This bits are cumulative, arg is a girq */ + XIVE_SYNC_EAS = 0x00000001, /* Sync irq source */ + XIVE_SYNC_QUEUE = 0x00000002, /* Sync irq target */ +}; + +/* Dump options */ +enum { + XIVE_DUMP_TM_HYP = 0, + XIVE_DUMP_TM_POOL = 1, + XIVE_DUMP_TM_OS = 2, + XIVE_DUMP_TM_USER = 3, + XIVE_DUMP_VP = 4, + XIVE_DUMP_EMU_STATE = 5, +}; + +/* "type" argument options for OPAL_IMC_COUNTERS_* calls */ +enum { + OPAL_IMC_COUNTERS_NEST = 1, + OPAL_IMC_COUNTERS_CORE = 2, + OPAL_IMC_COUNTERS_TRACE = 3, +}; + + +/* PCI p2p descriptor */ +#define OPAL_PCI_P2P_ENABLE 0x1 +#define OPAL_PCI_P2P_LOAD 0x2 +#define OPAL_PCI_P2P_STORE 0x4 + +enum { + OPAL_PCI_P2P_INITIATOR = 0, + OPAL_PCI_P2P_TARGET = 1, +}; + +/* MPIPL update operations */ +enum opal_mpipl_ops { + OPAL_MPIPL_ADD_RANGE = 0, + OPAL_MPIPL_REMOVE_RANGE = 1, + OPAL_MPIPL_REMOVE_ALL = 2, + OPAL_MPIPL_FREE_PRESERVED_MEMORY= 3, +}; + +/* Tag will point to various metadata area. Kernel will + * use tag to get metadata value. + */ +enum opal_mpipl_tags { + OPAL_MPIPL_TAG_CPU = 0, + OPAL_MPIPL_TAG_OPAL = 1, + OPAL_MPIPL_TAG_KERNEL = 2, + OPAL_MPIPL_TAG_BOOT_MEM = 3, +}; + +/* Preserved memory details */ +struct opal_mpipl_region { + __be64 src; + __be64 dest; + __be64 size; +}; + +/* Structure version */ +#define OPAL_MPIPL_VERSION 0x01 + +struct opal_mpipl_fadump { + u8 version; + u8 reserved[7]; + __be32 crashing_pir; /* OPAL crashing CPU PIR */ + __be32 cpu_data_version; + __be32 cpu_data_size; + __be32 region_cnt; + struct opal_mpipl_region region[]; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* __OPAL_API_H */ diff --git a/roms/skiboot/include/opal-dump.h b/roms/skiboot/include/opal-dump.h new file mode 100644 index 000000000..bc1b8768d --- /dev/null +++ b/roms/skiboot/include/opal-dump.h @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __OPAL_DUMP_H +#define __OPAL_DUMP_H + +/* + * Dump region ids + * + * 0x01 - 0x3F : OPAL + * 0x40 - 0x7F : Reserved for future use + * 0x80 - 0xFF : Kernel + * + */ +#define DUMP_REGION_OPAL_START 0x01 +#define DUMP_REGION_OPAL_END 0x3F +#define DUMP_REGION_HOST_START OPAL_DUMP_REGION_HOST_START +#define DUMP_REGION_HOST_END OPAL_DUMP_REGION_HOST_END + +#define DUMP_REGION_CONSOLE 0x01 +#define DUMP_REGION_HBRT_LOG 0x02 +#define DUMP_REGION_OPAL_MEMORY 0x03 +#define DUMP_REGION_KERNEL 0x80 + +/* Mainstore memory to be captured by FSP SYSDUMP */ +#define DUMP_TYPE_SYSDUMP 0xF5 +/* Mainstore memory to preserve during IPL */ +#define DUMP_TYPE_MPIPL 0x00 + +/* + * Memory Dump Source Table + * + * Format of this table is same as Memory Dump Source Table (MDST) + * defined in HDAT spec. + */ +struct mdst_table { + __be64 addr; + uint8_t data_region; /* DUMP_REGION_* */ + uint8_t dump_type; /* DUMP_TYPE_* */ + __be16 reserved; + __be32 size; +} __packed; + +/* Memory dump destination table (MDDT) */ +struct mddt_table { + __be64 addr; + uint8_t data_region; + uint8_t dump_type; + __be16 reserved; + __be32 size; +} __packed; + +/* + * Memory dump result table (MDRT) + * + * List of the memory ranges that have been included in the dump. This table is + * filled by hostboot and passed to OPAL on second boot. OPAL/payload will use + * this table to extract the dump. + */ +struct mdrt_table { + __be64 src_addr; + __be64 dest_addr; + uint8_t data_region; + uint8_t dump_type; + __be16 reserved; + __be32 size; + __be64 padding; +} __packed; + +/* + * Processor Dump Area + * + * This contains the information needed for having processor + * state captured during a platform dump. + */ +struct proc_dump_area { + __be32 thread_size; /* Size of each thread register entry */ +#define PROC_DUMP_AREA_FORMAT_P9 0x1 /* P9 format */ + uint8_t version; /* P9 - 0x1 */ + uint8_t reserved[11]; + __be64 alloc_addr; /* Destination memory to place register data */ + __be32 reserved2; + __be32 alloc_size; /* Allocated size */ + __be64 dest_addr; /* Destination address */ + __be32 reserved3; + __be32 act_size; /* Actual data size */ +} __packed; + +struct proc_reg_data_hdr { + /* PIR value of the thread */ + __be32 pir; + /* 0x00 - 0x0F - The corresponding stop state of the core */ + uint8_t core_state; + uint8_t reserved[3]; + + uint32_t offset; /* Offset to Register Entries array */ + uint32_t ecnt; /* Number of entries */ + uint32_t esize; /* Alloc size of each array entry in bytes */ + uint32_t eactsz; /* Actual size of each array entry in bytes */ +} __packed; + +/* Architected register data content */ +#define ARCH_REG_TYPE_GPR 0x01 +#define ARCH_REG_TYPE_SPR 0x02 +struct proc_reg_data { + uint32_t reg_type; /* ARCH_REG_TYPE_* */ + uint32_t reg_num; + uint64_t reg_val; +} __packed; + +/* Metadata to capture before triggering MPIPL */ +struct mpipl_metadata { + /* Crashing PIR is required to create OPAL dump */ + uint32_t crashing_pir; + /* Kernel expects OPAL to presrve tag and pass it back via OPAL API */ + uint64_t kernel_tag; + /* Post MPIPL kernel boot memory size */ + uint64_t boot_mem_size; +} __packed; + +/* init opal dump */ +extern void opal_mpipl_init(void); + +/* Save metadata before triggering MPIPL */ +void opal_mpipl_save_crashing_pir(void); + +/* Reserve memory to capture OPAL dump */ +extern void opal_mpipl_reserve_mem(void); + +/* Check MPIPL enabled or not */ +extern bool is_mpipl_enabled(void); + +#endif /* __OPAL_DUMP_H */ diff --git a/roms/skiboot/include/opal-internal.h b/roms/skiboot/include/opal-internal.h new file mode 100644 index 000000000..f6ca7ac32 --- /dev/null +++ b/roms/skiboot/include/opal-internal.h @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Internal header for OPAL API related things in skiboot + * + * Copyright 2013-2019 IBM Corp. + */ + +#ifndef __OPAL_INTERNAL_H +#define __OPAL_INTERNAL_H + + +#include <skiboot.h> + +/* An opal table entry */ +struct opal_table_entry { + void *func; + u32 token; + u32 nargs; +}; + +#ifdef __CHECKER__ +#define __opal_func_test_arg(__func, __nargs) 0 +#else +#define __opal_func_test_arg(__func, __nargs) \ + sizeof(__func( __test_args##__nargs )) +#endif + +#define opal_call(__tok, __func, __nargs) \ +static struct opal_table_entry __e_##__func __used __section(".opal_table") = \ +{ .func = __func, .token = __tok, \ + .nargs = __nargs + 0 * __opal_func_test_arg(__func, __nargs) } + +/* Make sure function takes args they claim. Look away now... */ +#define __test_args0 +#define __test_args1 0 +#define __test_args2 0,0 +#define __test_args3 0,0,0 +#define __test_args4 0,0,0,0 +#define __test_args5 0,0,0,0,0 +#define __test_args6 0,0,0,0,0,0 +#define __test_args7 0,0,0,0,0,0,0 + +extern struct opal_table_entry __opal_table_start[]; +extern struct opal_table_entry __opal_table_end[]; + +extern uint64_t opal_pending_events; + +extern struct dt_node *opal_node; + +extern void opal_table_init(void); +extern void opal_update_pending_evt(uint64_t evt_mask, uint64_t evt_values); +uint64_t opal_dynamic_event_alloc(void); +void opal_dynamic_event_free(uint64_t event); +extern void add_opal_node(void); + +#define opal_register(token, func, nargs) \ + __opal_register((token) + 0*__opal_func_test_arg(func, nargs), \ + (func), (nargs)) +extern void __opal_register(uint64_t token, void *func, unsigned num_args); + +int64_t opal_quiesce(uint32_t shutdown_type, int32_t cpu); + +/* Warning: no locking at the moment, do at init time only + * + * XXX TODO: Add the big RCU-ish "opal API lock" to protect us here + * which will also be used for other things such as runtime updates + */ +extern void opal_add_poller(void (*poller)(void *data), void *data); +extern void opal_del_poller(void (*poller)(void *data)); +extern void opal_run_pollers(void); + +/* + * Warning: no locking, only call that from the init processor + */ +extern void opal_add_host_sync_notifier(bool (*notify)(void *data), void *data); +extern void opal_del_host_sync_notifier(bool (*notify)(void *data), void *data); + +/* + * Opal internal function prototype + */ +struct OpalHMIEvent; +extern int occ_msg_queue_occ_reset(void); + +extern unsigned long top_of_ram; + +/* + * Returns true if the address is valid, false otherwise + * + * Checks if the passed address belongs to real address space + * or 0xc000... kernel address space. It also checks that + * addr <= total physical memory. The magic value 60 comes + * from 60 bit real address mentioned in section 5.7 of the + * Power ISA (Book 3S). + */ +static inline bool opal_addr_valid(const void *addr) +{ + unsigned long val = (unsigned long)addr; + if ((val >> 60) != 0xc && (val >> 60) != 0x0) + return false; + val &= ~0xf000000000000000UL; + if (val > top_of_ram) + return false; + return true; +} + +#endif /* __OPAL_INTERNAL_H */ diff --git a/roms/skiboot/include/opal-msg.h b/roms/skiboot/include/opal-msg.h new file mode 100644 index 000000000..2028c79d0 --- /dev/null +++ b/roms/skiboot/include/opal-msg.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __OPALMSG_H +#define __OPALMSG_H + +#include <opal.h> + +/* + * It dictates the number of asynchronous tokens available at the kernel, + * ideally the value matches to the number of modules using async + * infrastructure, but not necessarily the same.. + */ +#define OPAL_MAX_ASYNC_COMP 16 + +/* Max size of struct opal_msg */ +#define OPAL_MSG_SIZE (64 * 1024) + +/* opal_msg fixed parameters size */ +#define OPAL_MSG_HDR_SIZE (offsetof(struct opal_msg, params)) +#define OPAL_MSG_FIXED_PARAMS_SIZE \ + (sizeof(struct opal_msg) - OPAL_MSG_HDR_SIZE) + +int _opal_queue_msg(enum opal_msg_type msg_type, void *data, + void (*consumed)(void *data, int status), + size_t params_size, const void *params); + +#define opal_queue_msg(msg_type, data, cb, ...) \ + _opal_queue_msg(msg_type, data, cb, \ + sizeof((__be64[]) {__VA_ARGS__}), \ + (__be64[]) {__VA_ARGS__}); + +void opal_init_msg(void); + +#endif /* __OPALMSG_H */ diff --git a/roms/skiboot/include/opal.h b/roms/skiboot/include/opal.h new file mode 100644 index 000000000..6a19229d7 --- /dev/null +++ b/roms/skiboot/include/opal.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __OPAL_H +#define __OPAL_H + +#include <types.h> +#include <opal-api.h> +#include <opal-internal.h> + +#endif /* __OPAL_H */ diff --git a/roms/skiboot/include/p10_stop_api.H b/roms/skiboot/include/p10_stop_api.H new file mode 100644 index 000000000..2bcf03a45 --- /dev/null +++ b/roms/skiboot/include/p10_stop_api.H @@ -0,0 +1,239 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p10/procedures/utils/stopreg/p10_stop_api.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2021 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __P10_STOP_IMAGE_API_ +#define __P10_STOP_IMAGE_API_ + +#include <stdint.h> + +#ifdef __SKIBOOT__ + #include <skiboot.h> + #include <p9_stop_api.H> +#endif + +/// +/// @file p10_stop_api.H +/// @brief describes STOP API which create/manipulate STOP image. +/// +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : HB:HYP + +#ifdef __cplusplus +namespace stopImageSection +{ +#endif + +/** + * @brief all SPRs and MSR for which register restore is to be supported. + * @note STOP API design has built in support to accomodate 8 register of + * scope core and thread each. + */ +typedef enum +{ + PROC_STOP_SPR_DAWR = 180, // thread register + PROC_STOP_SPR_CIABR = 187, // thread register + PROC_STOP_SPR_DAWRX = 188, // thread register + PROC_STOP_SPR_HSPRG0 = 304, // thread register + PROC_STOP_SPR_HRMOR = 313, // core register + PROC_STOP_SPR_LPCR = 318, // thread register + PROC_STOP_SPR_HMEER = 337, // core register + PROC_STOP_SPR_PTCR = 464, // core register + PROC_STOP_SPR_USPRG0 = 496, // thread register + PROC_STOP_SPR_USPRG1 = 497, // thread register + PROC_STOP_SPR_URMOR = 505, // core register + PROC_STOP_SPR_SMFCTRL = 511, // thread register + PROC_STOP_SPR_LDBAR = 850, // thread register + PROC_STOP_SPR_PSSCR = 855, // thread register + PROC_STOP_SPR_PMCR = 884, // core register + PROC_STOP_SPR_HID = 1008, // core register + PROC_STOP_SPR_MSR = 2000, // thread register + +} CpuReg_p10_t; + +// /** +// * @brief lists all the bad error codes. +// */ +// typedef enum +// { +// STOP_SAVE_SUCCESS = 0, +// STOP_SAVE_ARG_INVALID_IMG = 1, +// STOP_SAVE_ARG_INVALID_REG = 2, +// STOP_SAVE_ARG_INVALID_THREAD = 3, +// STOP_SAVE_ARG_INVALID_MODE = 4, +// STOP_SAVE_ARG_INVALID_CORE = 5, +// STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6, +// STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7, +// STOP_SAVE_SCOM_INVALID_OPERATION = 8, +// STOP_SAVE_SCOM_INVALID_SECTION = 9, +// STOP_SAVE_SCOM_INVALID_ADDRESS = 10, +// STOP_SAVE_SCOM_INVALID_CHIPLET = 11, +// STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12, +// STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13, +// STOP_SAVE_FAIL = 14, // for internal failure within firmware. +// STOP_SAVE_SPR_ENTRY_MISSING = 15, +// STOP_SAVE_MAX_ENTRY_REACHED = 16, +// STOP_SAVE_SPR_BIT_POS_RESERVE = 17, +// } StopReturnCode_t; + +/** + * @brief summarizes all operations supported on scom entries of STOP image. + */ +typedef enum +{ + //enum members which are project agnostic + PROC_STOP_SCOM_OP_MIN = 0, + PROC_STOP_SCOM_APPEND = 1, + PROC_STOP_SCOM_REPLACE = 2, + PROC_STOP_SCOM_OR = 3, + PROC_STOP_SCOM_AND = 4, + PROC_STOP_SCOM_NOOP = 5, + PROC_STOP_SCOM_RESET = 6, + PROC_STOP_SCOM_OR_APPEND = 7, + PROC_STOP_SCOM_AND_APPEND = 8, + PROC_STOP_SCOM_OP_MAX = 9, + +} StopReturnCode_p10_t; + +/** + * @brief All subsections that contain scom entries in a STOP image. + */ +typedef enum +{ + PROC_STOP_SECTION_CORE = 1, + PROC_STOP_SECTION_L2 = 1, + PROC_STOP_SECTION_L3 = 2, + PROC_STOP_SECTION_CACHE = 2, +} ScomSection_p10_t; + +/** + * @brief versions pertaining relvant to STOP API. + */ +typedef enum +{ + STOP_API_VER = 0x00, + STOP_API_VER_CONTROL = 0x02, +} VersionList_t; + +/** + * @brief Summarizes bit position allocated to SPRs in save bit mask vector. + */ +typedef enum +{ + BIT_POS_CIABR = 0, + BIT_POS_DAWR = 1, + BIT_POS_DAWRX = 2, + BIT_POS_HSPRG0 = 3, + BIT_POS_LDBAR = 4, + BIT_POS_LPCR = 5, + BIT_POS_PSSCR = 6, + BIT_POS_MSR = 7, + BIT_POS_HID = 21, + BIT_POS_HMEER = 22, + BIT_POS_PMCR = 23, + BIT_POS_PTCR = 24, + BIT_POS_SMFCTRL = 28, + BIT_POS_USPRG0 = 29, + BIT_POS_USPRG1 = 30, +} SprBitPositionList_t; + + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief creates SCOM restore entry for a given scom adress in HOMER. + * @param i_pImage points to start address of HOMER image. + * @param i_scomAddress address associated with SCOM restore entry. + * @param i_scomData data associated with SCOM restore entry. + * @param i_operation operation type requested for API. + * @param i_section section of HOMER in which restore entry needs to be created. + * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise. + * @note It is an API for creating SCOM restore entry in HOMER. It is agnostic to + * generation of POWER processor. + */ + +StopReturnCode_t proc_stop_save_scom( void* const i_pImage, + const uint32_t i_scomAddress, + const uint64_t i_scomData, + const StopReturnCode_p10_t i_operation, + const ScomSection_p10_t i_section ); + +/** + * @brief initializes self save restore region of HOMER. + * @param[in] i_pImage points to base of HOMER image. + * @param[in] i_corePos position of the physical core. + * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise. + * @note It is an API for initializing self restore region in HOMER. It is agnostic to + * generation of POWER processor. + */ +StopReturnCode_t proc_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos ); + +/** + * @brief enables self save for a given set of SPRs + * @param[in] i_pImage points to start address of HOMER image. + * @param[in] i_pir PIR value associated with core and thread. + * @param[in] i_saveRegVector bit vector representing the SPRs that needs to be self saved. + * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise. + * @note It is an API for enabling self save of SPRs and it is agnostic to + * generation of POWER processor. + */ +StopReturnCode_t proc_stop_save_cpureg_control( void* i_pImage, + const uint64_t i_pir, + const uint32_t i_saveRegVector ); + +/** + * @brief creates an SPR restore entry in HOMER + * @param[in] i_pImage points to start address of HOMER image. + * @param[in] i_regId SPR number to be saved in HOMER + * @param[in] i_regData SPR data to be saved in HOMER + * @param[in] i_pir PIR value associated with core and thread. + * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise. + * @note It is an API for enabling self save of SPRs and it is agnostic to + * generation of POWER processor. + */ +StopReturnCode_t proc_stop_save_cpureg( void* const i_pImage, + const CpuReg_p10_t i_regId, + const uint64_t i_regData, + const uint64_t i_pir ); + +/** + * @brief initializes self-save region with specific instruction. + * @param[in] i_pImage points to start address of HOMER image. + * @param[in] i_corePos physical core's relative position within processor chip. + * @return STOP_SAVE_SUCCESS if self-save is initialized successfully, + * error code otherwise. + * @note API is project agnostic and is intended only for use case of HOMER build. + * There is no explicit effort to support any other use case. + */ +StopReturnCode_t proc_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos ); + +#ifdef __cplusplus +} // extern "C" +}; // namespace stopImageSection ends +#endif //__cplusplus + +#endif //__P10_STOP_IMAGE_API_ diff --git a/roms/skiboot/include/p9_stop_api.H b/roms/skiboot/include/p9_stop_api.H new file mode 100644 index 000000000..79abd0006 --- /dev/null +++ b/roms/skiboot/include/p9_stop_api.H @@ -0,0 +1,163 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __P9_STOP_IMAGE_API_ +#define __P9_STOP_IMAGE_API_ + +#include <stdint.h> + +#ifdef __SKIBOOT__ + #include <skiboot.h> +#endif + +/// +/// @file p9_stop_api.H +/// @brief describes STOP API which create/manipulate STOP image. +/// +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : HB:HYP + +#ifdef __cplusplus +namespace stopImageSection +{ +#endif + +/** + * @brief all SPRs and MSR for which register restore is to be supported. + * @note STOP API design has built in support to accomodate 8 register of + * scope core and thread each. + */ +typedef enum +{ + P9_STOP_SPR_DAWR = 180, // thread register + P9_STOP_SPR_HSPRG0 = 304, // thread register + P9_STOP_SPR_HRMOR = 313, // core register + P9_STOP_SPR_LPCR = 318, // thread register + P9_STOP_SPR_HMEER = 337, // core register + P9_STOP_SPR_LDBAR = 850, // thread register + P9_STOP_SPR_PSSCR = 855, // thread register + P9_STOP_SPR_PMCR = 884, // core register + P9_STOP_SPR_HID = 1008, // core register + P9_STOP_SPR_MSR = 2000, // thread register +} CpuReg_t; + +/** + * @brief lists all the bad error codes. + */ +typedef enum +{ + STOP_SAVE_SUCCESS = 0, + STOP_SAVE_ARG_INVALID_IMG = 1, + STOP_SAVE_ARG_INVALID_REG = 2, + STOP_SAVE_ARG_INVALID_THREAD = 3, + STOP_SAVE_ARG_INVALID_MODE = 4, + STOP_SAVE_ARG_INVALID_CORE = 5, + STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6, + STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7, + STOP_SAVE_SCOM_INVALID_OPERATION = 8, + STOP_SAVE_SCOM_INVALID_SECTION = 9, + STOP_SAVE_SCOM_INVALID_ADDRESS = 10, + STOP_SAVE_SCOM_INVALID_CHIPLET = 11, + STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12, + STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13, + STOP_SAVE_FAIL = 14, // for internal failure within firmware. +} StopReturnCode_t; + +/** + * @brief summarizes all operations supported on scom entries of STOP image. + */ +typedef enum +{ + P9_STOP_SCOM_OP_MIN = 0, + P9_STOP_SCOM_APPEND = 1, + P9_STOP_SCOM_REPLACE = 2, + P9_STOP_SCOM_OR = 3, + P9_STOP_SCOM_AND = 4, + P9_STOP_SCOM_NOOP = 5, + P9_STOP_SCOM_RESET = 6, + P9_STOP_SCOM_OR_APPEND = 7, + P9_STOP_SCOM_AND_APPEND = 8, + P9_STOP_SCOM_OP_MAX = 9 +} ScomOperation_t; + +/** + * @brief All subsections that contain scom entries in a STOP image. + */ +typedef enum +{ + P9_STOP_SECTION_MIN = 0, + P9_STOP_SECTION_CORE_SCOM = 1, + P9_STOP_SECTION_EQ_SCOM = 2, + P9_STOP_SECTION_L2 = 3, + P9_STOP_SECTION_L3 = 4, + P9_STOP_SECTION_MAX = 5 +} ScomSection_t; + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief Updates STOP image entry associated with CPU register. + * @param[in] i_pImage start address of homer image associated with processor. + * @param[in] i_regId id of SPR for which STOP image needs to be updated. + * @param[in] i_regData data to be restored in SPR register. + * @param[in] i_pir value of processor identification register (PIR) + * @return STOP_SAVE_SUCCESS SUCCESS if image is updated successfully, error + * code otherwise. + */ + +StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, + const CpuReg_t i_regId, + const uint64_t i_regData, + const uint64_t i_pir ); + +/** + * @brief Updates scom image entry associated with given core or cache in + * STOP section of homer image. + * @param[in] i_pImage start address of homer image of P9 chip. + * @param[in] i_scomAddress fully qualified address of SCOM register. + * @param[in] i_scomData data associated with SCOM register. + * @param[in] i_operation operation to be done on SCOM image entry. + * @param[in] i_section area to which given SCOM entry belongs. + * @return STOP_SAVE_SUCCESS if image is updated successfully, error code + * otherwise. + * @note API is intended to update SCOM image entry associated with given + * core or given part of a cache section. API doesn't validate if + * a given SCOM address really belongs to given section. + */ +StopReturnCode_t p9_stop_save_scom( void* const i_pImage, + const uint32_t i_scomAddress, + const uint64_t i_scomData, + const ScomOperation_t i_operation, + const ScomSection_t i_section ); + +#ifdef __cplusplus +} // extern "C" +}; // namespace stopImageSection ends +#endif //__cplusplus + +#endif //__P9_STOP_IMAGE_API_ diff --git a/roms/skiboot/include/pci-cfg.h b/roms/skiboot/include/pci-cfg.h new file mode 100644 index 000000000..72614fda1 --- /dev/null +++ b/roms/skiboot/include/pci-cfg.h @@ -0,0 +1,522 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * PCI Configuration space definitions + * + * Copyright 2013-2017 IBM Corp. + */ + +#ifndef __PCI_CFG_H +#define __PCI_CFG_H + +/* Common cfg space header */ +#define PCI_CFG_VENDOR_ID 0x0000 +#define PCI_CFG_DEVICE_ID 0x0002 +#define PCI_CFG_CMD 0x0004 +#define PCI_CFG_CMD_IO_EN 0x0001 +#define PCI_CFG_CMD_MEM_EN 0x0002 +#define PCI_CFG_CMD_BUS_MASTER_EN 0x0004 +#define PCI_CFG_CMD_PERR_RESP 0x0040 +#define PCI_CFG_CMD_SERR_EN 0x0100 +#define PCI_CFG_CMD_INTx_DIS 0x0400 +#define PCI_CFG_STAT 0x0006 +#define PCI_CFG_STAT_INTx 0x0008 +#define PCI_CFG_STAT_CAP 0x0010 +#define PCI_CFG_STAT_MDATAPERR 0x0100 +#define PCI_CFG_STAT_SENT_TABORT 0x0800 +#define PCI_CFG_STAT_RECV_TABORT 0x1000 +#define PCI_CFG_STAT_RECV_MABORT 0x2000 +#define PCI_CFG_STAT_SENT_SERR 0x4000 +#define PCI_CFG_STAT_RECV_PERR 0x8000 +#define PCI_CFG_REV_ID 0x0008 +#define PCI_CFG_CLAS_CODE 0x0009 +#define PCI_CFG_CACHE_LINE_SIZE 0x000c +#define PCI_CFG_LAT_TIMER 0x000d +#define PCI_CFG_HDR_TYPE 0x000e +#define PCI_CFG_BIST 0x000f +#define PCI_CFG_BAR0 0x0010 +#define PCI_CFG_BAR_TYPE 0x00000001 +#define PCI_CFG_BAR_TYPE_MEM 0x00000000 +#define PCI_CFG_BAR_TYPE_IO 0x00000001 +#define PCI_CFG_BAR_MEM64 0x00000004 +#define PCI_CFG_BAR_MEM_PREFETCH 0x00000008 +#define PCI_CFG_BAR1 0x0014 + +/* Type 0 fields */ +#define PCI_CFG_BAR2 0x0018 +#define PCI_CFG_BAR3 0x001c +#define PCI_CFG_BAR4 0x0020 +#define PCI_CFG_BAR5 0x0024 +#define PCI_CFG_CARDBUS_CIS 0x0028 +#define PCI_CFG_SUBSYS_VENDOR_ID 0x002c +#define PCI_CFG_SUBSYS_ID 0x002e +#define PCI_CFG_ROMBAR 0x0030 +#define PCI_CFG_CAP 0x0034 +#define PCI_CFG_INT_LINE 0x003c +#define PCI_CFG_INT_PIN 0x003d +#define PCI_CFG_INT_MIN_GNT 0x003e +#define PCI_CFG_INT_MAX_LAT 0x003f + +/* Type 1 fields */ +#define PCI_CFG_PRIMARY_BUS 0x0018 +#define PCI_CFG_SECONDARY_BUS 0x0019 +#define PCI_CFG_SUBORDINATE_BUS 0x001a +#define PCI_CFG_SEC_LAT_TIMER 0x001b +#define PCI_CFG_IO_BASE 0x001c +#define PCI_CFG_IO_LIMIT 0x001d +#define PCI_CFG_SECONDARY_STATUS 0x001e +#define PCI_CFG_MEM_BASE 0x0020 +#define PCI_CFG_MEM_LIMIT 0x0022 +#define PCI_CFG_PREF_MEM_BASE 0x0024 +#define PCI_CFG_PREF_MEM_LIMIT 0x0026 +#define PCI_CFG_PREF_MEM_BASE_U32 0x0028 +#define PCI_CFG_PREF_MEM_LIMIT_U32 0x002c +#define PCI_CFG_IO_BASE_U16 0x0030 +#define PCI_CFG_IO_LIMIT_U16 0x0032 +#define PCI_CFG_BR_CAP 0x0034 /* Same as type 0 */ +#define PCI_CFG_BR_ROMBAR 0x0038 /* Different from type 0 */ +#define PCI_CFG_BR_INT_LINE 0x003c /* Same as type 0 */ +#define PCI_CFG_BR_INT_PIN 0x003d /* Same as type 0 */ +#define PCI_CFG_BRCTL 0x003e +#define PCI_CFG_BRCTL_PERR_RESP_EN 0x0001 +#define PCI_CFG_BRCTL_SERR_EN 0x0002 +#define PCI_CFG_BRCTL_ISA_EN 0x0004 +#define PCI_CFG_BRCTL_VGA_EN 0x0008 +#define PCI_CFG_BRCTL_VGA_16BIT 0x0010 +#define PCI_CFG_BRCTL_MABORT_REPORT 0x0020 +#define PCI_CFG_BRCTL_SECONDARY_RESET 0x0040 +#define PCI_CFG_BRCTL_FAST_BACK2BACK 0x0080 +#define PCI_CFG_BRCTL_PRI_DISC_TIMER 0x0100 +#define PCI_CFG_BRCTL_SEC_DISC_TIMER 0x0200 +#define PCI_CFG_BRCTL_DISC_TIMER_STAT 0x0400 +#define PCI_CFG_BRCTL_DISC_TIMER_SERR 0x0800 + +/* + * Standard capabilties + */ +#define PCI_CFG_CAP_ID 0 +#define PCI_CFG_CAP_NEXT 1 + +/* PCI Power Management capability */ +#define PCI_CFG_CAP_ID_PM 1 + +/* PCI bridge subsystem ID capability */ +#define PCI_CFG_CAP_ID_SUBSYS_VID 0x0d +#define PCICAP_SUBSYS_VID_VENDOR 4 +#define PCICAP_SUBSYS_VID_DEVICE 6 + +/* Vendor specific capability */ +#define PCI_CFG_CAP_ID_VENDOR 9 + +/* PCI Express capability */ +#define PCI_CFG_CAP_ID_EXP 0x10 +/* PCI Express capability fields */ +#define PCICAP_EXP_CAPABILITY_REG 0x02 +#define PCICAP_EXP_CAP_VERSION 0x000f +#define PCICAP_EXP_CAP_TYPE 0x00f0 +#define PCIE_TYPE_ENDPOINT 0x0 +#define PCIE_TYPE_LEGACY 0x1 +#define PCIE_TYPE_ROOT_PORT 0x4 +#define PCIE_TYPE_SWITCH_UPPORT 0x5 +#define PCIE_TYPE_SWITCH_DNPORT 0x6 +#define PCIE_TYPE_PCIE_TO_PCIX 0x7 +#define PCIE_TYPE_PCIX_TO_PCIE 0x8 +#define PCIE_TYPE_RC_INTEGRATED 0x9 +#define PCIE_TYPE_RC_EVT_COLL 0xa +#define PCICAP_EXP_CAP_SLOT 0x0100 +#define PCICAP_EXP_CAP_MSI_NUM 0x3e00 +#define PCICAP_EXP_CAP_TCS_ROUTING 0x4000 +#define PCICAP_EXP_DEVCAP 0x04 +#define PCICAP_EXP_DEVCAP_MPSS 0x00000007 +#define PCIE_MPSS_128 0 +#define PCIE_MPSS_256 1 +#define PCIE_MPSS_512 2 +#define PCIE_MPSS_1024 3 +#define PCIE_MPSS_2048 4 +#define PCIE_MPSS_4096 5 +#define PCICAP_EXP_DEVCAP_PHANT 0x00000018 +#define PCIE_PHANTOM_NONE 0 +#define PCIE_PHANTOM_1MSB 1 +#define PCIE_PHANTOM_2MSB 2 +#define PCIE_PHANTOM_3MSB 3 +#define PCICAP_EXP_DEVCAP_EXTTAG 0x00000020 +#define PCICAP_EXP_DEVCAP_L0SL 0x000001c0 +#define PCIE_L0SL_MAX_64NS 0 +#define PCIE_L0SL_MAX_128NS 1 +#define PCIE_L0SL_MAX_256NS 2 +#define PCIE_L0SL_MAX_512NS 3 +#define PCIE_L0SL_MAX_1US 4 +#define PCIE_L0SL_MAX_2US 5 +#define PCIE_L0SL_MAX_4US 6 +#define PCIE_L0SL_MAX_NO_LIMIT 7 +#define PCICAP_EXP_DEVCAP_L1L 0x00000e00 +#define PCIE_L1L_MAX_1US 0 +#define PCIE_L1L_MAX_2US 1 +#define PCIE_L1L_MAX_4US 2 +#define PCIE_L1L_MAX_8US 3 +#define PCIE_L1L_MAX_16US 4 +#define PCIE_L1L_MAX_32US 5 +#define PCIE_L1L_MAX_64US 6 +#define PCIE_L1L_MAX_NO_LIMIT 7 +#define PCICAP_EXP_ROLE_BASED_ERR 0x00008000 +#define PCICAP_EXP_DEVCAP_PWRVAL 0x03fc0000 +#define PCICAP_EXP_DEVCAP_PWRSCA 0x0c000000 +#define PCIE_SLOT_PWR_SCALE_1x 0 +#define PCIE_SLOT_PWR_SCALE_0d1x 1 +#define PCIE_SLOT_PWR_SCALE_0d01x 2 +#define PCIE_SLOT_PWR_SCALE_0d001x 3 +#define PCICAP_EXP_DEVCAP_FUNC_RESET 0x10000000 +#define PCICAP_EXP_DEVCTL 0x08 +#define PCICAP_EXP_DEVCTL_CE_REPORT 0x0001 +#define PCICAP_EXP_DEVCTL_NFE_REPORT 0x0002 +#define PCICAP_EXP_DEVCTL_FE_REPORT 0x0004 +#define PCICAP_EXP_DEVCTL_UR_REPORT 0x0008 +#define PCICAP_EXP_DEVCTL_RELAX_ORD 0x0010 +#define PCICAP_EXP_DEVCTL_MPS 0x00e0 +#define PCIE_MPS_128B 0 +#define PCIE_MPS_256B 1 +#define PCIE_MPS_512B 2 +#define PCIE_MPS_1024B 3 +#define PCIE_MPS_2048B 4 +#define PCIE_MPS_4096B 5 +#define PCICAP_EXP_DEVCTL_EXT_TAG 0x0100 +#define PCICAP_EXP_DEVCTL_PHANTOM 0x0200 +#define PCICAP_EXP_DEVCTL_AUX_POW_PM 0x0400 +#define PCICAP_EXP_DEVCTL_NO_SNOOP 0x0800 +#define PCICAP_EXP_DEVCTL_MRRS 0x7000 +#define PCIE_MRSS_128B 0 +#define PCIE_MRSS_256B 1 +#define PCIE_MRSS_512B 2 +#define PCIE_MRSS_1024B 3 +#define PCIE_MRSS_2048B 4 +#define PCIE_MRSS_4096B 5 +#define PCICAP_EXP_DEVCTL_PCIX_RETRY 0x8000 /* PCIe - PCIX bridges only */ +#define PCICAP_EXP_DEVCTL_FUNC_RESET 0x8000 /* all others */ +#define PCICAP_EXP_DEVSTAT 0x0a +#define PCICAP_EXP_DEVSTAT_CE 0x0001 +#define PCICAP_EXP_DEVSTAT_NFE 0x0002 +#define PCICAP_EXP_DEVSTAT_FE 0x0004 +#define PCICAP_EXP_DEVSTAT_UE 0x0008 +#define PCICAP_EXP_DEVSTAT_AUX_POW 0x0010 +#define PCICAP_EXP_DEVSTAT_TPEND 0x0020 +#define PCICAP_EXP_LCAP 0x0c +#define PCICAP_EXP_LCAP_MAXSPD 0x0000000f +#define PCIE_LSPEED_VECBIT_0 0x1 +#define PCIE_LSPEED_VECBIT_1 0x2 +#define PCIE_LSPEED_VECBIT_2 0x3 +#define PCIE_LSPEED_VECBIT_3 0x4 +#define PCIE_LSPEED_VECBIT_4 0x5 +#define PCIE_LSPEED_VECBIT_5 0x6 +#define PCIE_LSPEED_VECBIT_6 0x7 +#define PCICAP_EXP_LCAP_MAXWDTH 0x000003f0 +#define PCIE_LWIDTH_1X 1 +#define PCIE_LWIDTH_2X 2 +#define PCIE_LWIDTH_4X 4 +#define PCIE_LWIDTH_8X 8 +#define PCIE_LWIDTH_12X 12 +#define PCIE_LWIDTH_16X 16 +#define PCIE_LWIDTH_32X 32 +#define PCICAP_EXP_LCAP_ASPM_L0S 0x00000400 +#define PCICAP_EXP_LCAP_ASPM_L1 0x00000800 +#define PCICAP_EXP_LCAP_L0S_EXLT 0x00007000 +#define PCIE_L0S_EXLT_LESS_64NS 0 +#define PCIE_L0S_EXLT_64NS_128NS 1 +#define PCIE_L0S_EXLT_128NS_256NS 2 +#define PCIE_L0S_EXLT_256NS_512NS 3 +#define PCIE_L0S_EXLT_512NS_1US 4 +#define PCIE_L0S_EXLT_1US_2US 5 +#define PCIE_L0S_EXLT_2US_4US 6 +#define PCIE_L0S_EXLT_MORE_4US 7 +#define PCICAP_EXP_LCAP_L1_EXLT 0x00038000 +#define PCIE_L1_EXLT_LESS_1US 0 +#define PCIE_L1_EXLT_1US_2US 1 +#define PCIE_L1_EXLT_2US_4US 2 +#define PCIE_L1_EXLT_4US_8US 3 +#define PCIE_L1_EXLT_8US_16US 4 +#define PCIE_L1_EXLT_16US_32US 5 +#define PCIE_L1_EXLT_32US_64US 6 +#define PCIE_L1_EXLT_MORE_64US 7 +#define PCICAP_EXP_LCAP_CLK_PM 0x00040000 +#define PCICAP_EXP_LCAP_SURP_DWN_ERR 0x00080000 +#define PCICAP_EXP_LCAP_DL_ACT_REP 0x00100000 +#define PCICAP_EXP_LCAP_LNKBWDTH_NOTF 0x00200000 +#define PCICAP_EXP_LCAP_ASPM_OPT_CMPL 0x00400000 +#define PCICAP_EXP_LCAP_PORTNUM 0xff000000 +#define PCICAP_EXP_LCTL 0x10 +#define PCICAP_EXP_LCTL_ASPM_L0S 0x0001 +#define PCICAP_EXP_LCTL_ASPM_L1 0x0002 +#define PCICAP_EXP_LCTL_RCB 0x0008 /* RO on root ports */ +#define PCICAP_EXP_LCTL_LINK_DIS 0x0010 +#define PCICAP_EXP_LCTL_LINK_RETRAIN 0x0020 +#define PCICAP_EXP_LCTL_COMMON_CLK 0x0040 +#define PCICAP_EXP_LCTL_EXT_SYNCH 0x0080 +#define PCICAP_EXP_LCTL_CLOCK_PM 0x0100 +#define PCICAP_EXP_LCTL_HW_AWIDTH_DIS 0x0200 +#define PCICAP_EXP_LCTL_LBWM_INT_EN 0x0400 +#define PCICAP_EXP_LCTL_LAWD_INT_EN 0x0800 +#define PCICAP_EXP_LSTAT 0x12 +#define PCICAP_EXP_LSTAT_SPEED 0x000f /* use PCIE_LSPEED_* consts */ +#define PCICAP_EXP_LSTAT_WIDTH 0x03f0 /* use PCIE_LWIDTH_* consts */ +#define PCICAP_EXP_LSTAT_TRAINING 0x0800 +#define PCICAP_EXP_LSTAT_SLOTCLKCFG 0x1000 +#define PCICAP_EXP_LSTAT_DLLL_ACT 0x2000 +#define PCICAP_EXP_LSTAT_LBWM_STAT 0x4000 +#define PCICAP_EXP_LSTAT_LAWS_STAT 0x8000 +#define PCICAP_EXP_SLOTCAP 0x14 +#define PCICAP_EXP_SLOTCAP_ATTNB 0x00000001 +#define PCICAP_EXP_SLOTCAP_PWCTRL 0x00000002 +#define PCICAP_EXP_SLOTCAP_MRLSENS 0x00000004 +#define PCICAP_EXP_SLOTCAP_ATTNI 0x00000008 +#define PCICAP_EXP_SLOTCAP_PWRI 0x00000010 +#define PCICAP_EXP_SLOTCAP_HPLUG_SURP 0x00000020 +#define PCICAP_EXP_SLOTCAP_HPLUG_CAP 0x00000040 +#define PCICAP_EXP_SLOTCAP_SPLVA 0x00007f80 +#define PCICAP_EXP_SLOTCAP_SPLSC 0x00018000 +#define PCICAP_EXP_SLOTCAP_EIP 0x00020000 +#define PCICAP_EXP_SLOTCAP_NO_CMDCOMP 0x00040000 +#define PCICAP_EXP_SLOTCAP_PSLOT 0xfff80000 +#define PCICAP_EXP_SLOTCTL 0x18 +#define PCICAP_EXP_SLOTCTL_ATTNB 0x0001 +#define PCICAP_EXP_SLOTCTL_PFLT 0x0002 +#define PCICAP_EXP_SLOTCTL_MRLSENSE 0x0004 +#define PCICAP_EXP_SLOTCTL_PDETECT 0x0008 +#define PCICAP_EXP_SLOTCTL_CMDCOMPINT 0x0010 +#define PCICAP_EXP_SLOTCTL_HPINT 0x0020 +#define PCICAP_EXP_SLOTCTL_ATTNI 0x00c0 +#define PCIE_INDIC_ON 1 +#define PCIE_INDIC_BLINK 2 +#define PCIE_INDIC_OFF 3 +#define PCICAP_EXP_SLOTCTL_PWRI 0x0300 /* Use PCIE_INDIC_* consts */ +#define PCICAP_EXP_SLOTCTL_PWRCTLR 0x0400 +#define PCICAP_EXP_SLOTCTL_EIC 0x0800 +#define PCICAP_EXP_SLOTCTL_DLLSTCHG 0x1000 +#define PCICAP_EXP_SLOTSTAT 0x1a +#define PCICAP_EXP_SLOTSTAT_ATTNBCH 0x0001 +#define PCICAP_EXP_SLOTSTAT_PWRFLTCH 0x0002 +#define PCICAP_EXP_SLOTSTAT_MRLSENSCH 0x0004 +#define PCICAP_EXP_SLOTSTAT_PDETECTCH 0x0008 +#define PCICAP_EXP_SLOTSTAT_CMDCOMPCH 0x0010 +#define PCICAP_EXP_SLOTSTAT_MRLSENSST 0x0020 +#define PCICAP_EXP_SLOTSTAT_PDETECTST 0x0040 +#define PCICAP_EXP_SLOTSTAT_EIS 0x0080 +#define PCICAP_EXP_SLOTSTAT_DLLSTCH 0x0100 +#define PCICAP_EXP_RC 0x1c +#define PCICAP_EXP_RC_SYSERR_ON_CE 0x0001 +#define PCICAP_EXP_RC_SYSERR_ON_NFE 0x0002 +#define PCICAP_EXP_RC_SYSERR_ON_FE 0x0004 +#define PCICAP_EXP_RC_PME_INT_EN 0x0008 +#define PCICAP_EXP_RC_CRS_VISIBLE 0x0010 +#define PCICAP_EXP_RCAP 0x1e +#define PCICAP_EXP_RCAP_CRS_VISIBLE 0x0001 +#define PCICAP_EXP_RSTAT 0x20 +#define PCICAP_EXP_RSTAT_PME_RID 0x0000ffff +#define PCICAP_EXP_RSTAT_PME_STATUS 0x00010000 +#define PCICAP_EXP_RSTAT_PME_PENDING 0x00020000 +#define PCIECAP_EXP_DCAP2 0x24 +#define PCICAP_EXP_DCAP2_CMPTOUT 0x0000000f +#define PCICAP_EXP_DCAP2_CMPTOUT_DIS 0x00000010 +#define PCICAP_EXP_DCAP2_ARI_FWD 0x00000020 +#define PCICAP_EXP_DCAP2_ATOMIC_RTE 0x00000040 +#define PCICAP_EXP_DCAP2_ATOMIC32 0x00000080 +#define PCICAP_EXP_DCAP2_ATOMIC64 0x00000100 +#define PCICAP_EXP_DCAP2_CAS128 0x00000200 +#define PCICAP_EXP_DCAP2_NORO_PRPR 0x00000400 +#define PCICAP_EXP_DCAP2_LTR 0x00000800 +#define PCICAP_EXP_DCAP2_TPHCOMP 0x00001000 +#define PCICAP_EXP_DCAP2_TPHCOMP_EXT 0x00002000 +#define PCICAP_EXP_DCAP2_OBFF_MSG 0x00040000 +#define PCICAP_EXP_DCAP2_OBFF_WAKE 0x00080000 +#define PCICAP_EXP_DCAP2_EXTFMT 0x00100000 +#define PCICAP_EXP_DCAP2_EETLP_PFX 0x00200000 +#define PCICAP_EXP_DCAP2_MAXEETP 0x00c00000 +#define PCIE_EETLPP_1 1 +#define PCIE_EETLPP_2 2 +#define PCIE_EETLPP_3 3 +#define PCIE_EETLPP_4 0 +#define PCICAP_EXP_DCTL2 0x28 +#define PCICAP_EXP_DCTL2_CMPTOUT 0x000f +#define PCICAP_EXP_DCTL2_CMPTOUT_DIS 0x0010 +#define PCICAP_EXP_DCTL2_ARI_FWD 0x0020 +#define PCICAP_EXP_DCTL2_ATOMIC_REQ 0x0040 +#define PCICAP_EXP_DCTL2_ATOMIC_EGBLK 0x0080 +#define PCICAP_EXP_DCTL2_IDO_REQ 0x0100 +#define PCICAP_EXP_DCTL2_IDO_COMPL 0x0200 +#define PCICAP_EXP_DCTL2_LTR 0x0400 +#define PCICAP_EXP_DCTL2_OBFF 0x6000 +#define PCIE_OBFF_MODE_DISABLED 0 +#define PCIE_OBFF_MODE_MSG_A 1 +#define PCIE_OBFF_MODE_MSG_B 2 +#define PCIE_OBFF_MODE_WAKE 3 +#define PCICAP_EXP_DCTL2_EETLPP_BLK 0x8000 +#define PCICAP_EXP_DSTA2 0x2a +#define PCICAP_EXP_LCAP2 0x2c +#define PCICAP_EXP_LCAP2_SP_2d5GTs 0x00000002 +#define PCICAP_EXP_LCAP2_SP_5d0GTs 0x00000004 +#define PCICAP_EXP_LCAP2_SP_8d0GTs 0x00000008 +#define PCICAP_EXP_LCAP2_XLINK 0x00000100 +#define PCICAP_EXP_LCTL2 0x30 +#define PCICAP_EXP_LCTL2_TLSPD 0x000f /* use PCIE_LSPEED_ consts */ +#define PCICAP_EXP_LCTL2_ENTER_COMPL 0x0010 +#define PCICAP_EXP_LCTL2_HWAUTSPDIS 0x0020 +#define PCICAP_EXP_LCTL2_SEL_DEEMPH 0x0040 +#define PCICAP_EXP_LCTL2_XMTMARG 0x0380 +#define PCICAP_EXP_LCTL2_ENTER_MCOMPL 0x0400 +#define PCICAP_EXP_LCTL2_COMPL_SOS 0x0800 +#define PCICAP_EXP_LCTL2_CMPPDEM 0xf000 +#define PCICAP_EXP_LSTA2 0x32 +#define PCICAP_EXP_LSTA2_DEMPH_LVL 0x0001 +#define PCICAP_EXP_LSTA2_EQ_COMPLETE 0x0002 +#define PCICAP_EXP_LSTA2_EQ_PH1_OK 0x0004 +#define PCICAP_EXP_LSTA2_EQ_PH2_OK 0x0008 +#define PCICAP_EXP_LSTA2_EQ_PH3_OK 0x0010 +#define PCICAP_EXP_LSTA2_LINK_EQ_REQ 0x0020 +#define PCICAP_EXP_SCAP2 0x34 +#define PCICAP_EXP_SCTL2 0x38 +#define PCICAP_EXP_SSTA2 0x3a + +/* + * PCI-E Extended capabilties + */ +#define PCI_CFG_ECAP_START 0x100 +#define PCI_CFG_ECAP_ID 0x0000ffff +#define PCI_CFG_ECAP_VERS 0x000f0000 +#define PCI_CFG_ECAP_NEXT 0xfff00000 + +/* AER Ext. Capability */ +#define PCIECAP_ID_AER 0x0001 +#define PCIECAP_AER_UE_STATUS 0x04 +#define PCIECAP_AER_UE_DLP 0x00000010 +#define PCIECAP_AER_UE_SURPRISE_DOWN 0x00000020 +#define PCIECAP_AER_UE_POISON_TLP 0x00001000 +#define PCIECAP_AER_UE_FLOW_CTL_PROT 0x00002000 +#define PCIECAP_AER_UE_COMPL_TIMEOUT 0x00004000 +#define PCIECAP_AER_UE_COMPL_ABORT 0x00008000 +#define PCIECAP_AER_UE_UNEXP_COMPL 0x00010000 +#define PCIECAP_AER_UE_RECV_OVFLOW 0x00020000 +#define PCIECAP_AER_UE_MALFORMED_TLP 0x00040000 +#define PCIECAP_AER_UE_ECRC 0x00080000 +#define PCIECAP_AER_UE_UNSUPP_REQ 0x00100000 +#define PCIECAP_AER_UE_ACS_VIOLATION 0x00200000 +#define PCIECAP_AER_UE_INTERNAL 0x00400000 +#define PCIECAP_AER_UE_MC_BLKD_TLP 0x00800000 +#define PCIECAP_AER_UE_ATOMIC_EGBLK 0x01000000 +#define PCIECAP_AER_UE_TLP_PRFX_BLK 0x02000000 +#define PCIECAP_AER_UE_MASK 0x08 +#define PCIECAP_AER_UE_MASK_DLLP 0x00000010 +#define PCIECAP_AER_UE_MASK_SURPRISE_DOWN 0x00000020 +#define PCIECAP_AER_UE_MASK_POISON_TLP 0x00001000 +#define PCIECAP_AER_UE_MASK_FLOW_CTL_PROT 0x00002000 +#define PCIECAP_AER_UE_MASK_COMPL_TIMEOUT 0x00004000 +#define PCIECAP_AER_UE_MASK_COMPL_ABORT 0x00008000 +#define PCIECAP_AER_UE_MASK_UNEXP_COMPL 0x00010000 +#define PCIECAP_AER_UE_MASK_RECV_OVFLOW 0x00020000 +#define PCIECAP_AER_UE_MASK_MALFORMED_TLP 0x00040000 +#define PCIECAP_AER_UE_MASK_ECRC 0x00080000 +#define PCIECAP_AER_UE_MASK_UNSUPP_REQ 0x00100000 +#define PCIECAP_AER_UE_SEVERITY 0x0c +#define PCIECAP_AER_UE_SEVERITY_DLLP 0x00000010 +#define PCIECAP_AER_UE_SEVERITY_SURPRISE_DOWN 0x00000020 +#define PCIECAP_AER_UE_SEVERITY_POISON_TLP 0x00001000 +#define PCIECAP_AER_UE_SEVERITY_FLOW_CTL_PROT 0x00002000 +#define PCIECAP_AER_UE_SEVERITY_COMPL_TIMEOUT 0x00004000 +#define PCIECAP_AER_UE_SEVERITY_COMPL_ABORT 0x00008000 +#define PCIECAP_AER_UE_SEVERITY_UNEXP_COMPL 0x00010000 +#define PCIECAP_AER_UE_SEVERITY_RECV_OVFLOW 0x00020000 +#define PCIECAP_AER_UE_SEVERITY_MALFORMED_TLP 0x00040000 +#define PCIECAP_AER_UE_SEVERITY_ECRC 0x00080000 +#define PCIECAP_AER_UE_SEVERITY_UNSUPP_REQ 0x00100000 +#define PCIECAP_AER_UE_SEVERITY_INTERNAL 0x00400000 +#define PCIECAP_AER_CE_STATUS 0x10 +#define PCIECAP_AER_CE_RECVR_ERR 0x00000001 +#define PCIECAP_AER_CE_BAD_TLP 0x00000040 +#define PCIECAP_AER_CE_BAD_DLLP 0x00000080 +#define PCIECAP_AER_CE_REPLAY_ROLLVR 0x00000100 +#define PCIECAP_AER_CE_REPLAY_TMR_TO 0x00001000 +#define PCIECAP_AER_CE_ADV_NONFATAL 0x00002000 +#define PCIECAP_AER_CE_CORTD_INTERNAL 0x00004000 +#define PCIECAP_AER_CE_HDR_LOG_OVFL 0x00008000 +#define PCIECAP_AER_CE_MASK 0x14 +#define PCIECAP_AER_CE_MASK_RECVR_ERR 0x00000001 +#define PCIECAP_AER_CE_MASK_BAD_TLP 0x00000040 +#define PCIECAP_AER_CE_MASK_BAD_DLLP 0x00000080 +#define PCIECAP_AER_CE_MASK_REPLAY_ROLLVR 0x00000100 +#define PCIECAP_AER_CE_MASK_REPLAY_TMR_TO 0x00001000 +#define PCIECAP_AER_CE_MASK_ADV_NONFATAL 0x00002000 +#define PCIECAP_AER_CE_MASK_CORTD_INTERNAL 0x00004000 +#define PCIECAP_AER_CE_MASK_HDR_LOG_OVFL 0x00008000 +#define PCIECAP_AER_CAPCTL 0x18 +#define PCIECAP_AER_CAPCTL_FPTR 0x0000001f +#define PCIECAP_AER_CAPCTL_ECRCG_CAP 0x00000020 +#define PCIECAP_AER_CAPCTL_ECRCG_EN 0x00000040 +#define PCIECAP_AER_CAPCTL_ECRCC_CAP 0x00000080 +#define PCIECAP_AER_CAPCTL_ECRCC_EN 0x00000100 +#define PCIECAP_AER_CAPCTL_MHREC_CAP 0x00000200 +#define PCIECAP_AER_CAPCTL_MHREC_EN 0x00000400 +#define PCIECAP_AER_CAPCTL_TLPPL_PR 0x00000800 +#define PCIECAP_AER_HDR_LOG0 0x1c +#define PCIECAP_AER_HDR_LOG1 0x20 +#define PCIECAP_AER_HDR_LOG2 0x24 +#define PCIECAP_AER_HDR_LOG3 0x28 +#define PCIECAP_AER_RERR_CMD 0x2c +#define PCIECAP_AER_RERR_CMD_FE 0x00000001 +#define PCIECAP_AER_RERR_CMD_NFE 0x00000002 +#define PCIECAP_AER_RERR_CMD_CE 0x00000004 +#define PCIECAP_AER_RERR_STA 0x30 +#define PCIECAP_AER_RERR_STA_CORR 0x00000001 +#define PCIECAP_AER_RERR_STA_MCORR 0x00000002 +#define PCIECAP_AER_RERR_STA_FNF 0x00000004 +#define PCIECAP_AER_RERR_STA_MFNF 0x00000008 +#define PCIECAP_AER_RERR_F_UFATAL 0x00000010 +#define PCIECAP_AER_RERR_NFE 0x00000020 +#define PCIECAP_AER_RERR_FE 0x00000040 +#define PCIECAP_AER_RERR_MSINO 0xf8000000 +#define PCIECAP_AER_SRCID 0x34 +#define PCIECAP_AER_SRCID_CORR 0x0000ffff +#define PCIECAP_AER_SRCID_FNF 0xffff0000 +#define PCIECAP_AER_TLP_PFX_LOG0 0x38 +#define PCIECAP_AER_TLP_PFX_LOG1 0x3c +#define PCIECAP_AER_TLP_PFX_LOG2 0x40 +#define PCIECAP_AER_TLP_PFX_LOG3 0x44 + +/* SRIOV capability */ +#define PCIECAP_ID_SRIOV 0x10 +#define PCIECAP_SRIOV_CAP 0x04 +#define PCIECAP_SRIOV_CAP_VFM 0x01 +#define PCIECAP_SRIOV_CAP_INTR(x) ((x) >> 21) +#define PCIECAP_SRIOV_CTRL 0x08 +#define PCIECAP_SRIOV_CTRL_VFE 0x01 +#define PCIECAP_SRIOV_CTRL_VFM 0x02 +#define PCIECAP_SRIOV_CTRL_INTR 0x04 +#define PCIECAP_SRIOV_CTRL_MSE 0x08 +#define PCIECAP_SRIOV_CTRL_ARI 0x10 +#define PCIECAP_SRIOV_STATUS 0x0a +#define PCIECAP_SRIOV_STATUS_VFM 0x01 +#define PCIECAP_SRIOV_INITIAL_VF 0x0c +#define PCIECAP_SRIOV_TOTAL_VF 0x0e +#define PCIECAP_SRIOV_NUM_VF 0x10 +#define PCIECAP_SRIOV_FUNC_LINK 0x12 +#define PCIECAP_SRIOV_VF_OFFSET 0x14 +#define PCIECAP_SRIOV_VF_STRIDE 0x16 +#define PCIECAP_SRIOV_VF_DID 0x1a +#define PCIECAP_SRIOV_SUP_PGSIZE 0x1c +#define PCIECAP_SRIOV_SYS_PGSIZE 0x20 +#define PCIECAP_SRIOV_BAR 0x24 +#define PCIECAP_SRIOV_NUM_BARS 6 +#define PCIECAP_SRIOV_VFM 0x3c +#define PCIECAP_SRIOV_VFM_BIR(x) ((x) & 7) +#define PCIECAP_SRIOV_VFM_OFFSET(x) ((x) & ~7) +#define PCIECAP_SRIOV_VFM_UA 0x0 +#define PCIECAP_SRIOV_VFM_MI 0x1 +#define PCIECAP_SRIOV_VFM_MO 0x2 +#define PCIECAP_SRIOV_VFM_AV 0x3 + +/* Vendor specific extend capability */ +#define PCIECAP_ID_VNDR 0x0b +#define PCIECAP_VNDR_HDR 0x04 +#define PCIECAP_VNDR_HDR_ID_MASK 0x0000ffff +#define PCIECAP_VNDR_HDR_ID_LSH 0 +#define PCIECAP_VNDR_HDR_REV_MASK 0x000f0000 +#define PCIECAP_VNDR_HDR_REV_LSH 16 +#define PCIECAP_VNDR_HDR_LEN_MASK 0xfff00000 +#define PCIECAP_VNDR_HDR_LEN_LSH 20 + +#endif /* __PCI_CFG_H */ diff --git a/roms/skiboot/include/pci-quirk.h b/roms/skiboot/include/pci-quirk.h new file mode 100644 index 000000000..fe766db50 --- /dev/null +++ b/roms/skiboot/include/pci-quirk.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2016-2017 IBM Corp. */ + +#ifndef __PCI_QUIRK_H +#define __PCI_QUIRK_H + +#include <pci.h> + +#define PCI_ANY_ID 0xFFFF + +struct pci_quirk { + uint16_t vendor_id; + uint16_t device_id; + void (*fixup)(struct phb *, struct pci_device *); +}; + +void pci_handle_quirk(struct phb *phb, struct pci_device *pd); + +#endif /* __PCI_QUIRK_H */ diff --git a/roms/skiboot/include/pci-slot.h b/roms/skiboot/include/pci-slot.h new file mode 100644 index 000000000..5eabd5af5 --- /dev/null +++ b/roms/skiboot/include/pci-slot.h @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __PCI_SLOT_H +#define __PCI_SLOT_H + +#include <opal.h> +#include <device.h> +#include <timebase.h> +#include <timer.h> +#include <ccan/list/list.h> + +/* + * PCI Slot Info: Wired Lane Values + * + * Values 0 to 6 match slot map 1005. In case of *any* change here + * make sure to keep the lxvpd.c parsing code in sync *and* the + * corresponding label strings in pci.c + */ +#define PCI_SLOT_WIRED_LANES_UNKNOWN 0x00 +#define PCI_SLOT_WIRED_LANES_PCIE_X1 0x01 +#define PCI_SLOT_WIRED_LANES_PCIE_X2 0x02 +#define PCI_SLOT_WIRED_LANES_PCIE_X4 0x03 +#define PCI_SLOT_WIRED_LANES_PCIE_X8 0x04 +#define PCI_SLOT_WIRED_LANES_PCIE_X16 0x05 +#define PCI_SLOT_WIRED_LANES_PCIE_X32 0x06 +#define PCI_SLOT_WIRED_LANES_PCIX_32 0x07 +#define PCI_SLOT_WIRED_LANES_PCIX_64 0x08 + +/* PCI Slot Info: Bus Clock Values */ +#define PCI_SLOT_BUS_CLK_RESERVED 0x00 +#define PCI_SLOT_BUS_CLK_GEN_1 0x01 +#define PCI_SLOT_BUS_CLK_GEN_2 0x02 +#define PCI_SLOT_BUS_CLK_GEN_3 0x03 + +/* PCI Slot Info: Connector Type Values */ +#define PCI_SLOT_CONNECTOR_PCIE_EMBED 0x00 +#define PCI_SLOT_CONNECTOR_PCIE_X1 0x01 +#define PCI_SLOT_CONNECTOR_PCIE_X2 0x02 +#define PCI_SLOT_CONNECTOR_PCIE_X4 0x03 +#define PCI_SLOT_CONNECTOR_PCIE_X8 0x04 +#define PCI_SLOT_CONNECTOR_PCIE_X16 0x05 +#define PCI_SLOT_CONNECTOR_PCIE_NS 0x0E /* Non-Standard */ + +/* PCI Slot Info: Card Description Values */ +#define PCI_SLOT_DESC_NON_STANDARD 0x00 /* Embed/Non-Standard */ +#define PCI_SLOT_DESC_PCIE_FH_FL 0x00 /* Full Height, Full Length */ +#define PCI_SLOT_DESC_PCIE_FH_HL 0x01 /* Full Height, Half Length */ +#define PCI_SLOT_DESC_PCIE_HH_FL 0x02 /* Half Height, Full Length */ +#define PCI_SLOT_DESC_PCIE_HH_HL 0x03 /* Half Height, Half Length */ + +/* PCI Slot Info: Mechanicals Values */ +#define PCI_SLOT_MECH_NONE 0x00 +#define PCI_SLOT_MECH_RIGHT 0x01 +#define PCI_SLOT_MECH_LEFT 0x02 +#define PCI_SLOT_MECH_RIGHT_LEFT 0x03 + +/* PCI Slot Info: Power LED Control Values */ +#define PCI_SLOT_PWR_LED_CTL_NONE 0x00 /* No Control */ +#define PCI_SLOT_PWR_LED_CTL_FSP 0x01 /* FSP Controlled */ +#define PCI_SLOT_PWR_LED_CTL_KERNEL 0x02 /* Kernel Controlled */ + +/* PCI Slot Info: ATTN LED Control Values */ +#define PCI_SLOT_ATTN_LED_CTL_NONE 0x00 /* No Control */ +#define PCI_SLOT_ATTN_LED_CTL_FSP 0x01 /* FSP Controlled */ +#define PCI_SLOT_ATTN_LED_CTL_KERNEL 0x02 /* Kernel Controlled */ + +/* Attention LED */ +#define PCI_SLOT_ATTN_LED_OFF 0 +#define PCI_SLOT_ATTN_LED_ON 1 +#define PCI_SLOT_ATTN_LED_BLINK 2 + +/* Power state */ +#define PCI_SLOT_POWER_OFF 0 +#define PCI_SLOT_POWER_ON 1 + +/* + * We have hard and soft reset for slot. Hard reset requires + * power-off and then power-on, but soft reset only resets + * secondary bus. + */ +struct pci_slot; +struct pci_slot_ops { + /* For slot management */ + int64_t (*get_presence_state)(struct pci_slot *slot, uint8_t *val); + int64_t (*get_link_state)(struct pci_slot *slot, uint8_t *val); + int64_t (*get_power_state)(struct pci_slot *slot, uint8_t *val); + int64_t (*get_attention_state)(struct pci_slot *slot, uint8_t *val); + int64_t (*get_latch_state)(struct pci_slot *slot, uint8_t *val); + int64_t (*set_power_state)(struct pci_slot *slot, uint8_t val); + int64_t (*set_attention_state)(struct pci_slot *slot, uint8_t val); + + /* SM based functions for reset */ + void (*prepare_link_change)(struct pci_slot *slot, bool is_up); + int64_t (*poll_link)(struct pci_slot *slot); + int64_t (*creset)(struct pci_slot *slot); + int64_t (*freset)(struct pci_slot *slot); + int64_t (*hreset)(struct pci_slot *slot); + int64_t (*run_sm)(struct pci_slot *slot); + int64_t (*completed_sm_run)(struct pci_slot *slot, uint64_t err); + + /* Auxillary functions */ + void (*add_properties)(struct pci_slot *slot, struct dt_node *np); +}; + +/* + * The PCI slot state is split up into base and number. With this + * design, the individual platforms can introduce their own PCI + * slot states with addition to the base. Eventually, the base + * state can be recognized by PCI slot core. + */ +#define PCI_SLOT_STATE_MASK 0xFFFFFF00 +#define PCI_SLOT_STATE_NORMAL 0x00000000 +#define PCI_SLOT_STATE_LINK 0x00000100 +#define PCI_SLOT_STATE_LINK_START_POLL (PCI_SLOT_STATE_LINK + 1) +#define PCI_SLOT_STATE_LINK_DELAY_FINALIZED (PCI_SLOT_STATE_LINK + 2) +#define PCI_SLOT_STATE_LINK_POLLING (PCI_SLOT_STATE_LINK + 3) +#define PCI_SLOT_STATE_HRESET 0x00000200 +#define PCI_SLOT_STATE_HRESET_START (PCI_SLOT_STATE_HRESET + 1) +#define PCI_SLOT_STATE_HRESET_HOLD (PCI_SLOT_STATE_HRESET + 2) +#define PCI_SLOT_STATE_FRESET 0x00000300 +#define PCI_SLOT_STATE_FRESET_POWER_OFF (PCI_SLOT_STATE_FRESET + 1) +#define PCI_SLOT_STATE_CRESET 0x00000400 +#define PCI_SLOT_STATE_CRESET_START (PCI_SLOT_STATE_CRESET + 1) +#define PCI_SLOT_STATE_GPOWER 0x00000500 +#define PCI_SLOT_STATE_GPOWER_START (PCI_SLOT_STATE_GPOWER + 1) +#define PCI_SLOT_STATE_SPOWER 0x00000600 +#define PCI_SLOT_STATE_SPOWER_START (PCI_SLOT_STATE_SPOWER + 1) +#define PCI_SLOT_STATE_SPOWER_DONE (PCI_SLOT_STATE_SPOWER + 2) +#define PCI_SLOT_STATE_GPRESENCE 0x00000700 +#define PCI_SLOT_STATE_GPRESENCE_START (PCI_SLOT_STATE_GPRESENCE + 1) + + +struct pci_slot { + uint32_t flags; +#define PCI_SLOT_FLAG_BOOTUP 0x1 +#define PCI_SLOT_FLAG_FORCE_POWERON 0x2 +#define PCI_SLOT_FLAG_BROKEN_PDC 0x4 +#define PCI_SLOT_FLAG_ENFORCE 0x8 + + struct phb *phb; + struct pci_device *pd; + + /* Identifier */ + uint64_t id; + struct timer timer; + uint64_t async_token; + uint8_t power_state; + + /* Slot information */ + uint8_t pluggable; + uint8_t surprise_pluggable; + uint8_t power_ctl; + uint8_t power_led_ctl; + uint8_t attn_led_ctl; + uint8_t connector_type; + uint8_t card_desc; + uint8_t card_mech; + uint8_t wired_lanes; + uint8_t power_limit; + + /* + * PCI slot is driven by state machine with polling function. + * @delay_tgt_tb tracks the current delay while @retries has + * the left rounds of delays. They should be set prior to + * switching next PCI slot state and changed (decreased) + * accordingly in the polling function. + */ + uint32_t state; + uint32_t retry_state; + uint16_t pcie_cap; + uint32_t link_cap; + uint32_t slot_cap; + uint64_t delay_tgt_tb; + uint64_t retries; + uint64_t link_retries; + struct pci_slot_ops ops; + struct pci_slot *peer_slot; + void *data; +}; + +#define PCI_SLOT_ID_PREFIX 0x8000000000000000UL +#define PCI_SLOT_ID(phb, bdfn) \ + (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb)->opal_id) +#define PCI_PHB_SLOT_ID(phb) ((phb)->opal_id) +#define PCI_SLOT_PHB_INDEX(id) ((id) & 0xfffful) +#define PCI_SLOT_BDFN(id) (((id) >> 16) & 0xfffful) + +static inline uint32_t pci_slot_add_flags(struct pci_slot *slot, + uint32_t flags) +{ + uint32_t old = 0; + + if (slot) { + old = slot->flags; + slot->flags |= flags; + } + + return old; +} + +static inline bool pci_slot_has_flags(struct pci_slot *slot, + uint32_t flags) +{ + if (!slot) + return false; + + if ((slot->flags & flags) == flags) + return true; + + return false; +} + +static inline uint32_t pci_slot_remove_flags(struct pci_slot *slot, + uint32_t flags) +{ + uint32_t old = 0; + + if (slot) { + old = slot->flags; + slot->flags &= ~flags; + } + + return old; +} + +static inline void pci_slot_set_state(struct pci_slot *slot, uint32_t state) +{ + if (slot) + slot->state = state; +} + +static inline uint64_t pci_slot_set_sm_timeout(struct pci_slot *slot, + uint64_t dur) +{ + if (slot) + slot->delay_tgt_tb = mftb() + dur; + return dur; +} + +extern struct pci_slot *pci_slot_alloc(struct phb *phb, + struct pci_device *pd); +extern struct pci_slot *pcie_slot_create(struct phb *phb, + struct pci_device *pd); +extern struct pci_slot *pcie_slot_create_dynamic(struct phb *phb, + struct pci_device *pd); + +extern void pci_slot_add_dt_properties(struct pci_slot *slot, + struct dt_node *np); +extern struct pci_slot *pci_slot_find(uint64_t id); + +extern void pci_slot_add_loc(struct pci_slot *slot, + struct dt_node *np, const char *label); + +/* DT based slot map */ + +extern struct dt_node *dt_slots; +extern struct dt_node *map_pci_dev_to_slot(struct phb *phb, + struct pci_device *pd); + +#endif /* __PCI_SLOT_H */ diff --git a/roms/skiboot/include/pci-virt.h b/roms/skiboot/include/pci-virt.h new file mode 100644 index 000000000..137f67d8a --- /dev/null +++ b/roms/skiboot/include/pci-virt.h @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#ifndef __PCI_VIRT_H +#define __PCI_VIRT_H + +#include <ccan/list/list.h> + +enum { + PCI_VIRT_CFG_NORMAL, + PCI_VIRT_CFG_RDONLY, + PCI_VIRT_CFG_W1CLR, + PCI_VIRT_CFG_MAX +}; + +struct pci_virt_device { + uint32_t bdfn; + uint32_t cfg_size; + uint8_t *config[PCI_VIRT_CFG_MAX]; + struct list_head pcrf; + struct list_node node; + void *data; +}; + +extern void pci_virt_cfg_read_raw(struct pci_virt_device *pvd, + uint32_t space, uint32_t offset, + uint32_t size, uint32_t *data); +extern void pci_virt_cfg_write_raw(struct pci_virt_device *pvd, + uint32_t space, uint32_t offset, + uint32_t size, uint32_t data); +extern struct pci_cfg_reg_filter *pci_virt_add_filter( + struct pci_virt_device *pvd, + uint32_t start, uint32_t len, + uint32_t flags, pci_cfg_reg_func func, + void *data); +extern int64_t pci_virt_cfg_read(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t size, + uint32_t *data); +extern int64_t pci_virt_cfg_write(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t size, + uint32_t data); +extern struct pci_virt_device *pci_virt_find_device(struct phb *phb, + uint32_t bdfn); +extern struct pci_virt_device *pci_virt_add_device(struct phb *phb, + uint32_t bdfn, + uint32_t cfg_size, + void *data); + +/* Config space accessors */ +#define PCI_VIRT_CFG_NORMAL_RD(d, o, s, v) \ + pci_virt_cfg_read_raw(d, PCI_VIRT_CFG_NORMAL, o, s, v) +#define PCI_VIRT_CFG_NORMAL_WR(d, o, s, v) \ + pci_virt_cfg_write_raw(d, PCI_VIRT_CFG_NORMAL, o, s, v) +#define PCI_VIRT_CFG_RDONLY_RD(d, o, s, v) \ + pci_virt_cfg_read_raw(d, PCI_VIRT_CFG_RDONLY, o, s, v) +#define PCI_VIRT_CFG_RDONLY_WR(d, o, s, v) \ + pci_virt_cfg_write_raw(d, PCI_VIRT_CFG_RDONLY, o, s, v) +#define PCI_VIRT_CFG_W1CLR_RD(d, o, s, v) \ + pci_virt_cfg_read_raw(d, PCI_VIRT_CFG_W1CLR, o, s, v) +#define PCI_VIRT_CFG_W1CLR_WR(d, o, s, v) \ + pci_virt_cfg_write_raw(d, PCI_VIRT_CFG_W1CLR, o, s, v) + +#define PCI_VIRT_CFG_INIT(d, o, s, v, r, w) \ + do { \ + PCI_VIRT_CFG_NORMAL_WR(d, o, s, v); \ + PCI_VIRT_CFG_RDONLY_WR(d, o, s, r); \ + PCI_VIRT_CFG_W1CLR_WR(d, o, s, w); \ + } while (0) +#define PCI_VIRT_CFG_INIT_RO(d, o, s, v) \ + PCI_VIRT_CFG_INIT(d, o, s, v, 0xffffffff, 0) + +#endif /* __VIRT_PCI_H */ diff --git a/roms/skiboot/include/pci.h b/roms/skiboot/include/pci.h new file mode 100644 index 000000000..eb23a6d9b --- /dev/null +++ b/roms/skiboot/include/pci.h @@ -0,0 +1,506 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __PCI_H +#define __PCI_H + +#include <opal.h> +#include <device.h> +#include <lock.h> +#include <bitmap.h> +#include <ccan/list/list.h> + +#define PCITRACE(_p, _bdfn, fmt, a...) \ + prlog(PR_TRACE, "PHB#%04x:%02x:%02x.%x " fmt, \ + (_p)->opal_id, \ + PCI_BUS_NUM(_bdfn), \ + PCI_DEV(_bdfn), PCI_FUNC(_bdfn), ## a) +#define PCIDBG(_p, _bdfn, fmt, a...) \ + prlog(PR_DEBUG, "PHB#%04x:%02x:%02x.%x " fmt, \ + (_p)->opal_id, \ + PCI_BUS_NUM(_bdfn), \ + PCI_DEV(_bdfn), PCI_FUNC(_bdfn), ## a) +#define PCINOTICE(_p, _bdfn, fmt, a...) \ + prlog(PR_NOTICE, "PHB#%04x:%02x:%02x.%x " fmt, \ + (_p)->opal_id, \ + PCI_BUS_NUM(_bdfn), \ + PCI_DEV(_bdfn), PCI_FUNC(_bdfn), ## a) +#define PCIERR(_p, _bdfn, fmt, a...) \ + prlog(PR_ERR, "PHB#%04x:%02x:%02x.%x " fmt, \ + (_p)->opal_id, \ + PCI_BUS_NUM(_bdfn), \ + PCI_DEV(_bdfn), PCI_FUNC(_bdfn), ## a) + +struct pci_device; +struct pci_cfg_reg_filter; + +typedef int64_t (*pci_cfg_reg_func)(void *dev, + struct pci_cfg_reg_filter *pcrf, + uint32_t offset, uint32_t len, + uint32_t *data, bool write); +typedef void (*pci_cap_free_data_func)(void *data); +struct pci_cfg_reg_filter { + uint32_t flags; +#define PCI_REG_FLAG_READ 0x1 +#define PCI_REG_FLAG_WRITE 0x2 +#define PCI_REG_FLAG_MASK 0x3 + uint32_t start; + uint32_t len; + uint8_t *data; + pci_cfg_reg_func func; + struct list_node link; +}; + +/* + * While this might not be necessary in the long run, the existing + * Linux kernels expect us to provide a device-tree that contains + * a representation of all PCI devices below the host bridge. Thus + * we need to perform a bus scan. We don't need to assign MMIO/IO + * resources, but we do need to assign bus numbers in a way that + * is going to be compatible with the HW constraints for PE filtering + * that is naturally aligned power of twos for ranges below a bridge. + * + * Thus the structure pci_device is used for the tracking of the + * detected devices and the later generation of the device-tree. + * + * We do not keep a separate structure for a bus, however a device + * can have children in which case a device is a bridge. + * + * Because this is likely to change, we avoid putting too much + * information in that structure nor relying on it for anything + * else but the construction of the flat device-tree. + */ +struct pci_device { + uint16_t bdfn; + bool is_bridge; + bool is_multifunction; + bool is_vf; + uint8_t dev_type; /* PCIE */ + uint8_t primary_bus; + uint8_t secondary_bus; + uint8_t subordinate_bus; + uint32_t scan_map; + + uint32_t vdid; + uint32_t sub_vdid; +#define PCI_VENDOR_ID(x) ((x) & 0xFFFF) +#define PCI_DEVICE_ID(x) ((x) >> 16) + uint32_t class; + uint64_t cap_list; + struct { + uint32_t pos; + void *data; + pci_cap_free_data_func free_func; + } cap[64]; + uint32_t mps; /* Max payload size capability */ + + uint32_t pcrf_start; + uint32_t pcrf_end; + struct list_head pcrf; + + /* + * Relaxed ordering is a feature which allows PCIe devices accessing GPU + * memory to bypass the normal PCIe ordering rules to increase + * performance. It is enabled on a per-PEC basis so every device on a + * PEC must support it before we can enable it. + */ + bool allow_relaxed_ordering; + + struct dt_node *dn; + struct pci_slot *slot; + struct pci_device *parent; + struct phb *phb; + struct list_head children; + struct list_node link; +}; + +static inline void pci_set_cap(struct pci_device *pd, int id, int pos, + void *data, pci_cap_free_data_func free_func, + bool ext) +{ + if (!ext) { + pd->cap_list |= (0x1ul << id); + pd->cap[id].pos = pos; + pd->cap[id].data = data; + pd->cap[id].free_func = free_func; + } else { + pd->cap_list |= (0x1ul << (id + 32)); + pd->cap[id + 32].pos = pos; + pd->cap[id + 32].data = data; + pd->cap[id + 32].free_func = free_func; + } +} + +static inline bool pci_has_cap(struct pci_device *pd, + int id, bool ext) +{ + if (!ext) + return !!(pd->cap_list & (0x1ul << id)); + else + return !!(pd->cap_list & (0x1ul << (id + 32))); +} + +static inline int pci_cap(struct pci_device *pd, + int id, bool ext) +{ + if (!ext) + return pd->cap[id].pos; + else + return pd->cap[id + 32].pos; +} + +static inline void *pci_cap_data(struct pci_device *pd, int id, bool ext) +{ + if (!ext) + return pd->cap[id].data; + else + return pd->cap[id + 32].data; +} + +/* + * When generating the device-tree, we need to keep track of + * the LSI mapping & swizzle it. This state structure is + * passed by the PHB to pci_add_nodes() and will be used + * internally. + * + * We assume that the interrupt parent (PIC) #address-cells + * is 0 and #interrupt-cells has a max value of 2. + */ +struct pci_lsi_state { +#define MAX_INT_SIZE 2 + uint32_t int_size; /* #cells */ + uint32_t int_val[4][MAX_INT_SIZE]; /* INTA...INTD */ + uint32_t int_parent[4]; +}; + +/* + * NOTE: All PCI functions return negative OPAL error codes + * + * In addition, some functions may return a positive timeout + * value or some other state information, see the description + * of individual functions. If nothing is specified, it's + * just an error code or 0 (success). + * + * Functions that operate asynchronously will return a positive + * delay value and will require the ->poll() op to be called after + * that delay. ->poll() will then return success, a negative error + * code, or another delay. + * + * Note: If an asynchronous function returns 0, it has completed + * successfully and does not require a call to ->poll(). Similarly + * if ->poll() is called while no operation is in progress, it will + * simply return 0 (success) + * + * Note that all functions except ->lock() itself assume that the + * caller is holding the PHB lock. + * + * TODO: Add more interfaces to control things like link width + * reduction for power savings etc... + */ + +struct phb; +extern int last_phb_id; + +struct phb_ops { + /* + * Config space ops + */ + int64_t (*cfg_read8)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint8_t *data); + int64_t (*cfg_read16)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint16_t *data); + int64_t (*cfg_read32)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t *data); + int64_t (*cfg_write8)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint8_t data); + int64_t (*cfg_write16)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint16_t data); + int64_t (*cfg_write32)(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t data); + + int64_t (*get_reserved_pe_number)(struct phb *phb); + + /* + * Device init method is called after a device has been detected + * and before probing further. It can alter things like scan_map + * for bridge ports etc... + */ + int (*device_init)(struct phb *phb, struct pci_device *device, + void *data); + void (*device_remove)(struct phb *phb, struct pci_device *pd); + + /* PHB final fixup is called after PCI probing is completed */ + void (*phb_final_fixup)(struct phb *phb); + + /* + * EEH methods + * + * The various arguments are identical to the corresponding + * OPAL functions + */ + int64_t (*eeh_freeze_status)(struct phb *phb, uint64_t pe_number, + uint8_t *freeze_state, + uint16_t *pci_error_type, + uint16_t *severity); + int64_t (*eeh_freeze_clear)(struct phb *phb, uint64_t pe_number, + uint64_t eeh_action_token); + int64_t (*eeh_freeze_set)(struct phb *phb, uint64_t pe_number, + uint64_t eeh_action_token); + int64_t (*err_inject)(struct phb *phb, uint64_t pe_number, + uint32_t type, uint32_t func, uint64_t addr, + uint64_t mask); + int64_t (*get_diag_data2)(struct phb *phb, void *diag_buffer, + uint64_t diag_buffer_len); + int64_t (*next_error)(struct phb *phb, uint64_t *first_frozen_pe, + uint16_t *pci_error_type, uint16_t *severity); + + /* + * Other IODA methods + * + * The various arguments are identical to the corresponding + * OPAL functions + */ + int64_t (*pci_reinit)(struct phb *phb, uint64_t scope, uint64_t data); + int64_t (*phb_mmio_enable)(struct phb *phb, uint16_t window_type, + uint16_t window_num, uint16_t enable); + + int64_t (*set_phb_mem_window)(struct phb *phb, uint16_t window_type, + uint16_t window_num, uint64_t addr, + uint64_t pci_addr, uint64_t size); + + int64_t (*map_pe_mmio_window)(struct phb *phb, uint64_t pe_number, + uint16_t window_type, uint16_t window_num, + uint16_t segment_num); + + int64_t (*set_pe)(struct phb *phb, uint64_t pe_number, + uint64_t bus_dev_func, uint8_t bus_compare, + uint8_t dev_compare, uint8_t func_compare, + uint8_t pe_action); + + int64_t (*set_peltv)(struct phb *phb, uint32_t parent_pe, + uint32_t child_pe, uint8_t state); + + int64_t (*map_pe_dma_window)(struct phb *phb, uint64_t pe_number, + uint16_t window_id, uint16_t tce_levels, + uint64_t tce_table_addr, + uint64_t tce_table_size, + uint64_t tce_page_size); + + int64_t (*map_pe_dma_window_real)(struct phb *phb, uint64_t pe_number, + uint16_t dma_window_number, + uint64_t pci_start_addr, + uint64_t pci_mem_size); + + int64_t (*set_option)(struct phb *phb, enum OpalPhbOption opt, + uint64_t setting); + int64_t (*get_option)(struct phb *phb, enum OpalPhbOption opt, + __be64 *setting); + + int64_t (*set_mve)(struct phb *phb, uint32_t mve_number, + uint64_t pe_number); + + int64_t (*set_mve_enable)(struct phb *phb, uint32_t mve_number, + uint32_t state); + + int64_t (*set_xive_pe)(struct phb *phb, uint64_t pe_number, + uint32_t xive_num); + + int64_t (*get_msi_32)(struct phb *phb, uint64_t mve_number, + uint32_t xive_num, uint8_t msi_range, + uint32_t *msi_address, uint32_t *message_data); + + int64_t (*get_msi_64)(struct phb *phb, uint64_t mve_number, + uint32_t xive_num, uint8_t msi_range, + uint64_t *msi_address, uint32_t *message_data); + + int64_t (*ioda_reset)(struct phb *phb, bool purge); + + int64_t (*papr_errinjct_reset)(struct phb *phb); + + /* + * IODA2 PCI interfaces + */ + int64_t (*pci_msi_eoi)(struct phb *phb, uint32_t hwirq); + + /* TCE Kill abstraction */ + int64_t (*tce_kill)(struct phb *phb, uint32_t kill_type, + uint64_t pe_number, uint32_t tce_size, + uint64_t dma_addr, uint32_t npages); + + /* Put phb in capi mode or pcie mode */ + int64_t (*set_capi_mode)(struct phb *phb, uint64_t mode, + uint64_t pe_number); + + int64_t (*set_capp_recovery)(struct phb *phb); + + /* PCI peer-to-peer setup */ + void (*set_p2p)(struct phb *phb, uint64_t mode, uint64_t flags, + uint16_t pe_number); + + /* Get/set PBCQ Tunnel BAR register */ + void (*get_tunnel_bar)(struct phb *phb, uint64_t *addr); + int64_t (*set_tunnel_bar)(struct phb *phb, uint64_t addr); +}; + +enum phb_type { + phb_type_pci, + phb_type_pcix_v1, + phb_type_pcix_v2, + phb_type_pcie_v1, + phb_type_pcie_v2, + phb_type_pcie_v3, + phb_type_pcie_v4, + phb_type_npu_v2, + phb_type_npu_v2_opencapi, + phb_type_npu_v3, +}; + +/* Generic PCI NVRAM flags */ +extern bool verbose_eeh; +extern bool pci_tracing; + +void pci_nvram_init(void); + +struct phb { + struct dt_node *dt_node; + int opal_id; + uint32_t scan_map; + enum phb_type phb_type; + struct lock lock; + struct list_head devices; + struct list_head virt_devices; + const struct phb_ops *ops; + struct pci_lsi_state lstate; + uint32_t mps; + bitmap_t *filter_map; + + /* PCI-X only slot info, for PCI-E this is in the RC bridge */ + struct pci_slot *slot; + + /* Base location code used to generate the children one */ + const char *base_loc_code; + + /* Additional data the platform might need to attach */ + void *platform_data; +}; + +static inline void phb_lock(struct phb *phb) +{ + lock(&phb->lock); +} + +static inline bool phb_try_lock(struct phb *phb) +{ + return try_lock(&phb->lock); +} + +static inline void phb_unlock(struct phb *phb) +{ + unlock(&phb->lock); +} + +bool pci_check_clear_freeze(struct phb *phb); + +/* Config space ops wrappers */ +static inline int64_t pci_cfg_read8(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint8_t *data) +{ + return phb->ops->cfg_read8(phb, bdfn, offset, data); +} + +static inline int64_t pci_cfg_read16(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint16_t *data) +{ + return phb->ops->cfg_read16(phb, bdfn, offset, data); +} + +static inline int64_t pci_cfg_read32(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t *data) +{ + return phb->ops->cfg_read32(phb, bdfn, offset, data); +} + +static inline int64_t pci_cfg_write8(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint8_t data) +{ + return phb->ops->cfg_write8(phb, bdfn, offset, data); +} + +static inline int64_t pci_cfg_write16(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint16_t data) +{ + return phb->ops->cfg_write16(phb, bdfn, offset, data); +} + +static inline int64_t pci_cfg_write32(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t data) +{ + return phb->ops->cfg_write32(phb, bdfn, offset, data); +} + +/* Utilities */ +extern void pci_remove_bus(struct phb *phb, struct list_head *list); +extern uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus, + struct list_head *list, struct pci_device *parent, + bool scan_downstream); +extern void pci_add_device_nodes(struct phb *phb, + struct list_head *list, + struct dt_node *parent_node, + struct pci_lsi_state *lstate, + uint8_t swizzle); +extern int64_t pci_find_cap(struct phb *phb, uint16_t bdfn, uint8_t cap); +extern int64_t pci_find_ecap(struct phb *phb, uint16_t bdfn, uint16_t cap, + uint8_t *version); +extern void pci_init_capabilities(struct phb *phb, struct pci_device *pd); +extern bool pci_wait_crs(struct phb *phb, uint16_t bdfn, uint32_t *out_vdid); +extern void pci_restore_slot_bus_configs(struct pci_slot *slot); +extern void pci_device_init(struct phb *phb, struct pci_device *pd); +extern struct pci_device *pci_walk_dev(struct phb *phb, + struct pci_device *pd, + int (*cb)(struct phb *, + struct pci_device *, + void *), + void *userdata); +extern struct pci_device *pci_find_dev(struct phb *phb, uint16_t bdfn); +extern void pci_restore_bridge_buses(struct phb *phb, struct pci_device *pd); +extern struct pci_cfg_reg_filter *pci_find_cfg_reg_filter(struct pci_device *pd, + uint32_t start, uint32_t len); +extern int64_t pci_handle_cfg_filters(struct phb *phb, uint32_t bdfn, + uint32_t offset, uint32_t len, + uint32_t *data, bool write); +extern struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd, + uint32_t start, uint32_t len, + uint32_t flags, pci_cfg_reg_func func); + +/* Manage PHBs */ +#define OPAL_DYNAMIC_PHB_ID (~0) +extern int64_t pci_register_phb(struct phb *phb, int opal_id); +extern int64_t pci_unregister_phb(struct phb *phb); +extern struct phb *pci_get_phb(uint64_t phb_id); + +static inline struct phb *__pci_next_phb_idx(uint64_t *phb_id) { + struct phb *phb = NULL; + while (phb == NULL && *phb_id <= last_phb_id) { + phb = pci_get_phb((*phb_id)++); + } + return phb; +} + +#define for_each_phb(phb) \ + for (uint64_t __phb_idx = 0; \ + (phb = __pci_next_phb_idx(&__phb_idx)) ; ) + +/* Device tree */ +extern void pci_std_swizzle_irq_map(struct dt_node *dt_node, + struct pci_device *pd, + struct pci_lsi_state *lstate, + uint8_t swizzle); + +/* Initialize all PCI slots */ +extern void pci_init_slots(void); +extern int64_t pci_reset(void); + +extern void opal_pci_eeh_set_evt(uint64_t phb_id); +extern void opal_pci_eeh_clear_evt(uint64_t phb_id); + +#endif /* __PCI_H */ diff --git a/roms/skiboot/include/pel.h b/roms/skiboot/include/pel.h new file mode 100644 index 000000000..a0df7cc3c --- /dev/null +++ b/roms/skiboot/include/pel.h @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2014 IBM Corp. */ + +#ifndef __PEL_H +#define __PEL_H + +#include <compiler.h> +#include <errorlog.h> + +/* Data Structures for PEL data. */ + +#define PRIVATE_HEADER_SECTION_SIZE 48 +#define USER_HEADER_SECTION_SIZE 24 +#define SRC_SECTION_SIZE 80 +#define SRC_SUBSECTION_SIZE 4 +#define SRC_LENGTH 72 +#define OPAL_MAX_SRC_BYTES 32 +#define EXTENDED_HEADER_SECTION_SIZE 76 +#define MTMS_SECTION_SIZE 28 +#define IO_EVENT_SECTION_SIZE 16 + +#define OPAL_ELOG_VERSION 1 +#define OPAL_ELOG_SST 0 +#define OPAL_SRC_MAX_WORD_COUNT 8 + +#define OPAL_SRC_FORMAT 0x80 +#define OPAL_FAILING_SUBSYSTEM 0x82 + +#define OPAL_SYS_MODEL_LEN 8 +#define OPAL_SYS_SERIAL_LEN 12 +#define OPAL_VER_LEN 16 +#define OPAL_SYMPID_LEN 80 +#define OPAL_RC_NONE 0 + +#define OPAL_IO_MAX_RPC_DATA 216 +#define OPAL_SRC_SEC_VER 0x02 +#define OPAL_EXT_HRD_VER 0x01 + +/* Error log reporting action */ +#define ERRL_ACTION_REPORT 0x2000 +#define ERRL_ACTION_NONE 0x0000 + +enum elogSectionId { + ELOG_SID_PRIVATE_HEADER = 0x5048, /* PH */ + ELOG_SID_USER_HEADER = 0x5548, /* UH */ + ELOG_SID_EXTENDED_HEADER = 0x4548, /* EH */ + ELOG_SID_PRIMARY_SRC = 0x5053, /* PS */ + ELOG_SID_MACHINE_TYPE = 0x4D54, /* MT */ + ELOG_SID_SECONDARY_SRC = 0x5353, /* SS */ + ELOG_SID_CALL_HOME = 0x4348, /* CH */ + ELOG_SID_DUMP_LOCATOR = 0x4448, /* DH */ + ELOG_SID_SOFTWARE_ERROR = 0x5357, /* SW */ + ELOG_SID_PARTITION = 0x4C50, /* LP */ + ELOG_SID_LOGICAL_RESOURCE = 0x4C52, /* LR */ + ELOG_SID_HMC_ID = 0x484D, /* HM */ + ELOG_SID_EPOW = 0x4550, /* EP */ + ELOG_SID_IO_EVENT = 0x4945, /* IE */ + ELOG_SID_MFG_INFORMATION = 0x4D49, /* MI */ + ELOG_SID_USER_DEFINED = 0x5544 /* UD */ +}; + + +struct opal_v6_header { + __be16 id; /* section id */ + __be16 length; /* section length */ + uint8_t version; /* section version */ + uint8_t subtype; /* section sub-type id */ + __be16 component_id; /* component id of section creator */ +} __packed; + +/* opal_srctype */ +#define OPAL_SRC_TYPE_ERROR 0xBB + +#define OPAL_CID_SAPPHIRE 'K' /* creator ID for sapphire log */ +#define OPAL_CID_POWERNV 'P' /* creator ID for powernv log */ + +/* Origin of error, elog_origin */ +#define ORG_SAPPHIRE 1 +#define ORG_POWERNV 2 + +/* MAX time for error log commit */ +#define ERRORLOG_TIMEOUT_INTERVAL 180 + +/*struct opal_private head section_ */ +struct opal_private_header_section { + + struct opal_v6_header v6header; + __be32 create_date; + __be32 create_time; + __be32 commit_date; + __be32 commit_time; + + uint8_t creator_id; /* subsystem component id */ + __be16 reserved_0; + uint8_t section_count; /* number of sections in log */ + __be32 reserved_1; + __be32 creator_subid_hi; + __be32 creator_subid_lo; + __be32 plid; /* platform log id */ + __be32 log_entry_id; /* Unique log entry id */ +} __packed; + +/* opal user header section */ +struct opal_user_header_section { + + struct opal_v6_header v6header; + + uint8_t subsystem_id; /* subsystem id */ + uint8_t event_scope; + uint8_t event_severity; + uint8_t event_type; /* error/event severity */ + + __be32 reserved_0; + __be16 reserved_1; + __be16 action_flags; /* error action code */ + __be32 reserved_2; +} __packed; + +struct opal_src_section { + struct opal_v6_header v6header; + uint8_t version; + uint8_t flags; + uint8_t reserved_0; + uint8_t wordcount; + __be16 reserved_1; + __be16 srclength; + __be32 hexwords[OPAL_SRC_MAX_WORD_COUNT]; + char srcstring[OPAL_MAX_SRC_BYTES]; +} __packed; + +struct opal_extended_header_section { + struct opal_v6_header v6header; + char model[OPAL_SYS_MODEL_LEN]; + char serial_no[OPAL_SYS_SERIAL_LEN]; + char opal_release_version[OPAL_VER_LEN]; + char opal_subsys_version[OPAL_VER_LEN]; + __be16 reserved_0; + __be32 extended_header_date; + __be32 extended_header_time; + __be16 reserved_1; + uint8_t reserved_2; + uint8_t opal_symid_len; + char opalsymid[OPAL_SYMPID_LEN]; +} __packed; + +/* opal MTMS section */ +struct opal_mtms_section { + struct opal_v6_header v6header; + char model[OPAL_SYS_MODEL_LEN]; + char serial_no[OPAL_SYS_SERIAL_LEN]; +} __packed; + +/* User defined section */ +struct opal_user_section { + struct opal_v6_header v6header; + char dump[1]; +} __packed; + +/* The minimum size of a PEL record */ +#define PEL_MIN_SIZE (PRIVATE_HEADER_SECTION_SIZE + USER_HEADER_SECTION_SIZE \ + + SRC_SECTION_SIZE + EXTENDED_HEADER_SECTION_SIZE \ + + MTMS_SECTION_SIZE) + +size_t pel_size(struct errorlog *elog_data); +int create_pel_log(struct errorlog *elog_data, char *pel_buffer, + size_t pel_buffer_size) __warn_unused_result; + +#endif diff --git a/roms/skiboot/include/phb3-capp.h b/roms/skiboot/include/phb3-capp.h new file mode 100644 index 000000000..d228160e8 --- /dev/null +++ b/roms/skiboot/include/phb3-capp.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2017 IBM Corp. */ + +#ifndef __PHB3_CAPP_H +#define __PHB3_CAPP_H + +#define CAPP_SNP_ARRAY_ADDR_REG 0x2013028 +#define CAPP_APC_MASTER_ARRAY_ADDR_REG 0x201302A +#define CAPP_SNP_ARRAY_WRITE_REG 0x2013801 +#define CAPP_APC_MASTER_ARRAY_WRITE_REG 0x2013802 + +#define CAPP_FIR 0x2013000 +#define CAPP_FIR_MASK 0x2013003 +#define CAPP_FIR_ACTION0 0x2013006 +#define CAPP_FIR_ACTION1 0x2013007 +#define CAPP_ERR_RPT_CLR 0x2013013 +#define APC_MASTER_PB_CTRL 0x2013018 +#define APC_MASTER_CAPI_CTRL 0x2013019 +#define TRANSPORT_CONTROL 0x201301C +#define CANNED_PRESP_MAP0 0x201301D +#define CANNED_PRESP_MAP1 0x201301E +#define CANNED_PRESP_MAP2 0x201301F +#define CAPP_ERR_STATUS_CTRL 0x201300E +#define FLUSH_SUE_STATE_MAP 0x201300F +#define CAPP_TB 0x2013026 +#define CAPP_TFMR 0x2013027 +#define CAPP_EPOCH_TIMER_CTRL 0x201302C +#define FLUSH_UOP_CONFIG1 0x2013803 +#define FLUSH_UOP_CONFIG2 0x2013804 +#define SNOOP_CAPI_CONFIG 0x201301A + +/* + * Naples has two CAPP units, statically mapped: + * CAPP0 attached to PHB0, and CAPP1 attached to PHB1. + * The addresses of CAPP1 XSCOMS registers are 0x180 away. + */ +#define CAPP1_REG_OFFSET 0x180 + +#endif /* __PHB3_CAPP_H */ diff --git a/roms/skiboot/include/phb3-regs.h b/roms/skiboot/include/phb3-regs.h new file mode 100644 index 000000000..a1f28180c --- /dev/null +++ b/roms/skiboot/include/phb3-regs.h @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#ifndef __PHB3_REGS_H +#define __PHB3_REGS_H + +/* + * PHB registers + */ + +/* PHB Fundamental register set A */ +#define PHB_LSI_SOURCE_ID 0x100 +#define PHB_LSI_SRC_ID PPC_BITMASK(5,12) +#define PHB_DMA_CHAN_STATUS 0x110 +#define PHB_DMA_CHAN_ANY_ERR PPC_BIT(27) +#define PHB_DMA_CHAN_ANY_ERR1 PPC_BIT(28) +#define PHB_DMA_CHAN_ANY_FREEZE PPC_BIT(29) +#define PHB_CPU_LOADSTORE_STATUS 0x120 +#define PHB_CPU_LS_ANY_ERR PPC_BIT(27) +#define PHB_CPU_LS_ANY_ERR1 PPC_BIT(28) +#define PHB_CPU_LS_ANY_FREEZE PPC_BIT(29) +#define PHB_DMA_MSI_NODE_ID 0x128 +#define PHB_DMAMSI_NID_FIXED PPC_BIT(0) +#define PHB_DMAMSI_NID PPC_BITMASK(24,31) +#define PHB_CONFIG_DATA 0x130 +#define PHB_LOCK0 0x138 +#define PHB_CONFIG_ADDRESS 0x140 +#define PHB_CA_ENABLE PPC_BIT(0) +#define PHB_CA_BUS PPC_BITMASK(4,11) +#define PHB_CA_DEV PPC_BITMASK(12,16) +#define PHB_CA_FUNC PPC_BITMASK(17,19) +#define PHB_CA_BDFN PPC_BITMASK(4,19) /* bus,dev,func */ +#define PHB_CA_REG PPC_BITMASK(20,31) +#define PHB_CA_PE PPC_BITMASK(40,47) +#define PHB_LOCK1 0x148 +#define PHB_IVT_BAR 0x150 +#define PHB_IVT_BAR_ENABLE PPC_BIT(0) +#define PHB_IVT_BASE_ADDRESS PPC_BITMASK(14,48) +#define PHB_IVT_LENGTH PPC_BITMASK(52,63) +#define PHB_RBA_BAR 0x158 +#define PHB_RBA_BAR_ENABLE PPC_BIT(0) +#define PHB_RBA_BASE_ADDRESS PPC_BITMASK(14,55) +#define PHB_PHB3_CONFIG 0x160 +#define PHB_PHB3C_64B_TCE_EN PPC_BIT(2) +#define PHB_PHB3C_32BIT_MSI_EN PPC_BIT(8) +#define PHB_PHB3C_64BIT_MSI_EN PPC_BIT(14) +#define PHB_PHB3C_M32_EN PPC_BIT(16) +#define PHB_RTT_BAR 0x168 +#define PHB_RTT_BAR_ENABLE PPC_BIT(0) +#define PHB_RTT_BASE_ADDRESS PPC_BITMASK(14,46) +#define PHB_PELTV_BAR 0x188 +#define PHB_PELTV_BAR_ENABLE PPC_BIT(0) +#define PHB_PELTV_BASE_ADDRESS PPC_BITMASK(14,50) +#define PHB_M32_BASE_ADDR 0x190 +#define PHB_M32_BASE_MASK 0x198 +#define PHB_M32_START_ADDR 0x1a0 +#define PHB_PEST_BAR 0x1a8 +#define PHB_PEST_BAR_ENABLE PPC_BIT(0) +#define PHB_PEST_BASE_ADDRESS PPC_BITMASK(14,51) +#define PHB_M64_UPPER_BITS 0x1f0 +#define PHB_INTREP_TIMER 0x1f8 +#define PHB_DMARD_SYNC 0x200 +#define PHB_RTC_INVALIDATE 0x208 +#define PHB_RTC_INVALIDATE_ALL PPC_BIT(0) +#define PHB_RTC_INVALIDATE_RID PPC_BITMASK(16,31) +#define PHB_TCE_KILL 0x210 +#define PHB_TCE_KILL_ALL PPC_BIT(0) +#define PHB_TCE_SPEC_CTL 0x218 +#define PHB_IODA_ADDR 0x220 +#define PHB_IODA_AD_AUTOINC PPC_BIT(0) +#define PHB_IODA_AD_TSEL PPC_BITMASK(11,15) +#define PHB_IODA_AD_TADR PPC_BITMASK(55,63) +#define PHB_IODA_DATA0 0x228 +#define PHB_FFI_REQUEST 0x238 +#define PHB_FFI_LOCK_CLEAR PPC_BIT(3) +#define PHB_FFI_REQUEST_ISN PPC_BITMASK(49,59) +#define PHB_FFI_LOCK 0x240 +#define PHB_XIVE_UPDATE 0x248 /* Broken in DD1 */ +#define PHB_PHB3_GEN_CAP 0x250 +#define PHB_PHB3_TCE_CAP 0x258 +#define PHB_PHB3_IRQ_CAP 0x260 +#define PHB_PHB3_EEH_CAP 0x268 +#define PHB_IVC_INVALIDATE 0x2a0 +#define PHB_IVC_INVALIDATE_ALL PPC_BIT(0) +#define PHB_IVC_INVALIDATE_SID PPC_BITMASK(16,31) +#define PHB_IVC_UPDATE 0x2a8 +#define PHB_IVC_UPDATE_ENABLE_P PPC_BIT(0) +#define PHB_IVC_UPDATE_ENABLE_Q PPC_BIT(1) +#define PHB_IVC_UPDATE_ENABLE_SERVER PPC_BIT(2) +#define PHB_IVC_UPDATE_ENABLE_PRI PPC_BIT(3) +#define PHB_IVC_UPDATE_ENABLE_GEN PPC_BIT(4) +#define PHB_IVC_UPDATE_ENABLE_CON PPC_BIT(5) +#define PHB_IVC_UPDATE_GEN_MATCH PPC_BITMASK(6, 7) +#define PHB_IVC_UPDATE_SERVER PPC_BITMASK(8, 23) +#define PHB_IVC_UPDATE_PRI PPC_BITMASK(24, 31) +#define PHB_IVC_UPDATE_GEN PPC_BITMASK(32,33) +#define PHB_IVC_UPDATE_P PPC_BITMASK(34,34) +#define PHB_IVC_UPDATE_Q PPC_BITMASK(35,35) +#define PHB_IVC_UPDATE_SID PPC_BITMASK(48,63) +#define PHB_PAPR_ERR_INJ_CTL 0x2b0 +#define PHB_PAPR_ERR_INJ_CTL_INB PPC_BIT(0) +#define PHB_PAPR_ERR_INJ_CTL_OUTB PPC_BIT(1) +#define PHB_PAPR_ERR_INJ_CTL_STICKY PPC_BIT(2) +#define PHB_PAPR_ERR_INJ_CTL_CFG PPC_BIT(3) +#define PHB_PAPR_ERR_INJ_CTL_RD PPC_BIT(4) +#define PHB_PAPR_ERR_INJ_CTL_WR PPC_BIT(5) +#define PHB_PAPR_ERR_INJ_CTL_FREEZE PPC_BIT(6) +#define PHB_PAPR_ERR_INJ_ADDR 0x2b8 +#define PHB_PAPR_ERR_INJ_ADDR_MMIO PPC_BITMASK(16,63) +#define PHB_PAPR_ERR_INJ_MASK 0x2c0 +#define PHB_PAPR_ERR_INJ_MASK_CFG PPC_BITMASK(4,11) +#define PHB_PAPR_ERR_INJ_MASK_CFG_ALL PPC_BITMASK(4,19) +#define PHB_PAPR_ERR_INJ_MASK_MMIO PPC_BITMASK(16,63) +#define PHB_ETU_ERR_SUMMARY 0x2c8 + +/* UTL registers */ +#define UTL_SYS_BUS_CONTROL 0x400 +#define UTL_STATUS 0x408 +#define UTL_SYS_BUS_AGENT_STATUS 0x410 +#define UTL_SYS_BUS_AGENT_ERR_SEVERITY 0x418 +#define UTL_SYS_BUS_AGENT_IRQ_EN 0x420 +#define UTL_SYS_BUS_BURST_SZ_CONF 0x440 +#define UTL_REVISION_ID 0x448 +#define UTL_BCLK_DOMAIN_DBG1 0x460 +#define UTL_BCLK_DOMAIN_DBG2 0x468 +#define UTL_BCLK_DOMAIN_DBG3 0x470 +#define UTL_BCLK_DOMAIN_DBG4 0x478 +#define UTL_BCLK_DOMAIN_DBG5 0x480 +#define UTL_BCLK_DOMAIN_DBG6 0x488 +#define UTL_OUT_POST_HDR_BUF_ALLOC 0x4c0 +#define UTL_OUT_POST_DAT_BUF_ALLOC 0x4d0 +#define UTL_IN_POST_HDR_BUF_ALLOC 0x4e0 +#define UTL_IN_POST_DAT_BUF_ALLOC 0x4f0 +#define UTL_OUT_NP_BUF_ALLOC 0x500 +#define UTL_IN_NP_BUF_ALLOC 0x510 +#define UTL_PCIE_TAGS_ALLOC 0x520 +#define UTL_GBIF_READ_TAGS_ALLOC 0x530 +#define UTL_PCIE_PORT_CONTROL 0x540 +#define UTL_PCIE_PORT_STATUS 0x548 +#define UTL_PCIE_PORT_ERROR_SEV 0x550 +#define UTL_PCIE_PORT_IRQ_EN 0x558 +#define UTL_RC_STATUS 0x560 +#define UTL_RC_ERR_SEVERITY 0x568 +#define UTL_RC_IRQ_EN 0x570 +#define UTL_EP_STATUS 0x578 +#define UTL_EP_ERR_SEVERITY 0x580 +#define UTL_EP_ERR_IRQ_EN 0x588 +#define UTL_PCI_PM_CTRL1 0x590 +#define UTL_PCI_PM_CTRL2 0x598 +#define UTL_GP_CTL1 0x5a0 +#define UTL_GP_CTL2 0x5a8 +#define UTL_PCLK_DOMAIN_DBG1 0x5b0 +#define UTL_PCLK_DOMAIN_DBG2 0x5b8 +#define UTL_PCLK_DOMAIN_DBG3 0x5c0 +#define UTL_PCLK_DOMAIN_DBG4 0x5c8 + +/* PCI-E Stack registers */ +#define PHB_PCIE_SYSTEM_CONFIG 0x600 +#define PHB_PCIE_SCONF_SLOT PPC_BIT(15) +#define PHB_PCIE_SCONF_MAXLINKSPEED PPC_BITMASK(32,35) +#define PHB_PCIE_BUS_NUMBER 0x608 +#define PHB_PCIE_SYSTEM_TEST 0x618 +#define PHB_PCIE_LINK_MANAGEMENT 0x630 +#define PHB_PCIE_LM_CHG_LINK_WIDTH PPC_BIT(0) +#define PHB_PCIE_LM_TGT_LINK_WIDTH PPC_BITMASK(2,7) +#define PHB_PCIE_LM_LINK_ACTIVE PPC_BIT(8) +#define PHB_PCIE_LM_DL_WCHG_PENDING PPC_BIT(9) +#define PHB_PCIE_LM_CHG_SPEED PPC_BIT(11) +#define PHB_PCIE_LM_TGT_SPEED PPC_BITMASK(12,15) +#define PHB_PCIE_DLP_TRAIN_CTL 0x640 +#define PHB_PCIE_DLP_TCTX_DISABLE PPC_BIT(1) +#define PHB_PCIE_DLP_TCRX_DISABLED PPC_BIT(16) +#define PHB_PCIE_DLP_INBAND_PRESENCE PPC_BIT(19) +#define PHB_PCIE_DLP_TC_DL_LINKUP PPC_BIT(21) +#define PHB_PCIE_DLP_TC_DL_PGRESET PPC_BIT(22) +#define PHB_PCIE_DLP_TC_DL_LINKACT PPC_BIT(23) +#define PHB_PCIE_SLOP_LOOPBACK_STATUS 0x648 +#define PHB_PCIE_SYS_LINK_INIT 0x668 +#define PHB_PCIE_UTL_CONFIG 0x670 +#define PHB_PCIE_DLP_CONTROL 0x678 +#define PHB_PCIE_UTL_ERRLOG1 0x680 +#define PHB_PCIE_UTL_ERRLOG2 0x688 +#define PHB_PCIE_UTL_ERRLOG3 0x690 +#define PHB_PCIE_UTL_ERRLOG4 0x698 +#define PHB_PCIE_DLP_ERRLOG1 0x6a0 +#define PHB_PCIE_DLP_ERRLOG2 0x6a8 +#define PHB_PCIE_DLP_ERR_STATUS 0x6b0 +#define PHB_PCIE_DLP_ERR_COUNTERS 0x6b8 +#define PHB_PCIE_UTL_ERR_INJECT 0x6c0 +#define PHB_PCIE_TLDLP_ERR_INJECT 0x6c8 +#define PHB_PCIE_LANE_EQ_CNTL0 0x6d0 +#define PHB_PCIE_LANE_EQ_CNTL1 0x6d8 +#define PHB_PCIE_LANE_EQ_CNTL2 0x6e0 +#define PHB_PCIE_LANE_EQ_CNTL3 0x6e8 +#define PHB_PCIE_STRAPPING 0x700 + +/* Fundamental register set B */ +#define PHB_VERSION 0x800 +#define PHB_RESET 0x808 +#define PHB_CONTROL 0x810 +#define PHB_AIB_RX_CRED_INIT_TIMER 0x818 +#define PHB_AIB_RX_CMD_CRED 0x820 +#define PHB_AIB_RX_DATA_CRED 0x828 +#define PHB_AIB_TX_CMD_CRED 0x830 +#define PHB_AIB_TX_DATA_CRED 0x838 +#define PHB_AIB_TX_CHAN_MAPPING 0x840 +#define PHB_AIB_TAG_ENABLE 0x858 +#define PHB_AIB_FENCE_CTRL 0x860 +#define PHB_TCE_TAG_ENABLE 0x868 +#define PHB_TCE_WATERMARK 0x870 +#define PHB_TIMEOUT_CTRL1 0x878 +#define PHB_TIMEOUT_CTRL2 0x880 +#define PHB_QUIESCE_DMA_G 0x888 +#define PHB_AIB_TAG_STATUS 0x900 +#define PHB_TCE_TAG_STATUS 0x908 + +/* FIR & Error registers */ +#define PHB_LEM_FIR_ACCUM 0xc00 +#define PHB_LEM_FIR_AND_MASK 0xc08 +#define PHB_LEM_FIR_OR_MASK 0xc10 +#define PHB_LEM_ERROR_MASK 0xc18 +#define PHB_LEM_ERROR_AND_MASK 0xc20 +#define PHB_LEM_ERROR_OR_MASK 0xc28 +#define PHB_LEM_ACTION0 0xc30 +#define PHB_LEM_ACTION1 0xc38 +#define PHB_LEM_WOF 0xc40 +#define PHB_ERR_STATUS 0xc80 +#define PHB_ERR1_STATUS 0xc88 +#define PHB_ERR_INJECT 0xc90 +#define PHB_ERR_LEM_ENABLE 0xc98 +#define PHB_ERR_IRQ_ENABLE 0xca0 +#define PHB_ERR_FREEZE_ENABLE 0xca8 +#define PHB_ERR_AIB_FENCE_ENABLE 0xcb0 +#define PHB_ERR_LOG_0 0xcc0 +#define PHB_ERR_LOG_1 0xcc8 +#define PHB_ERR_STATUS_MASK 0xcd0 +#define PHB_ERR1_STATUS_MASK 0xcd8 + +#define PHB_OUT_ERR_STATUS 0xd00 +#define PHB_OUT_ERR1_STATUS 0xd08 +#define PHB_OUT_ERR_INJECT 0xd10 +#define PHB_OUT_ERR_LEM_ENABLE 0xd18 +#define PHB_OUT_ERR_IRQ_ENABLE 0xd20 +#define PHB_OUT_ERR_FREEZE_ENABLE 0xd28 +#define PHB_OUT_ERR_AIB_FENCE_ENABLE 0xd30 +#define PHB_OUT_ERR_LOG_0 0xd40 +#define PHB_OUT_ERR_LOG_1 0xd48 +#define PHB_OUT_ERR_STATUS_MASK 0xd50 +#define PHB_OUT_ERR1_STATUS_MASK 0xd58 + +#define PHB_INA_ERR_STATUS 0xd80 +#define PHB_INA_ERR1_STATUS 0xd88 +#define PHB_INA_ERR_INJECT 0xd90 +#define PHB_INA_ERR_LEM_ENABLE 0xd98 +#define PHB_INA_ERR_IRQ_ENABLE 0xda0 +#define PHB_INA_ERR_FREEZE_ENABLE 0xda8 +#define PHB_INA_ERR_AIB_FENCE_ENABLE 0xdb0 +#define PHB_INA_ERR_LOG_0 0xdc0 +#define PHB_INA_ERR_LOG_1 0xdc8 +#define PHB_INA_ERR_STATUS_MASK 0xdd0 +#define PHB_INA_ERR1_STATUS_MASK 0xdd8 + +#define PHB_INB_ERR_STATUS 0xe00 +#define PHB_INB_ERR1_STATUS 0xe08 +#define PHB_INB_ERR_INJECT 0xe10 +#define PHB_INB_ERR_LEM_ENABLE 0xe18 +#define PHB_INB_ERR_IRQ_ENABLE 0xe20 +#define PHB_INB_ERR_FREEZE_ENABLE 0xe28 +#define PHB_INB_ERR_AIB_FENCE_ENABLE 0xe30 +#define PHB_INB_ERR_LOG_0 0xe40 +#define PHB_INB_ERR_LOG_1 0xe48 +#define PHB_INB_ERR_STATUS_MASK 0xe50 +#define PHB_INB_ERR1_STATUS_MASK 0xe58 + +/* Performance monitor & Debug registers */ +#define PHB_TRACE_CONTROL 0xf80 +#define PHB_PERFMON_CONFIG 0xf88 +#define PHB_PERFMON_CTR0 0xf90 +#define PHB_PERFMON_CTR1 0xf98 +#define PHB_PERFMON_CTR2 0xfa0 +#define PHB_PERFMON_CTR3 0xfa8 +#define PHB_HOTPLUG_OVERRIDE 0xfb0 +#define PHB_HPOVR_FORCE_RESAMPLE PPC_BIT(9) +#define PHB_HPOVR_PRESENCE_A PPC_BIT(10) +#define PHB_HPOVR_PRESENCE_B PPC_BIT(11) +#define PHB_HPOVR_LINK_ACTIVE PPC_BIT(12) +#define PHB_HPOVR_LINK_BIFURCATED PPC_BIT(13) +#define PHB_HPOVR_LINK_LANE_SWAPPED PPC_BIT(14) + +/* + * IODA2 on-chip tables + */ + +#define IODA2_TBL_LIST 1 +#define IODA2_TBL_LXIVT 2 +#define IODA2_TBL_IVC_CAM 3 +#define IODA2_TBL_RBA 4 +#define IODA2_TBL_RCAM 5 +#define IODA2_TBL_MRT 6 +#define IODA2_TBL_PESTA 7 +#define IODA2_TBL_PESTB 8 +#define IODA2_TBL_TVT 9 +#define IODA2_TBL_TCAM 10 +#define IODA2_TBL_TDR 11 +#define IODA2_TBL_M64BT 16 +#define IODA2_TBL_M32DT 17 +#define IODA2_TBL_PEEV 20 + +/* LXIVT */ +#define IODA2_LXIVT_SERVER PPC_BITMASK(8,23) +#define IODA2_LXIVT_PRIORITY PPC_BITMASK(24,31) +#define IODA2_LXIVT_NODE_ID PPC_BITMASK(56,63) + +/* IVT */ +#define IODA2_IVT_SERVER PPC_BITMASK(0,23) +#define IODA2_IVT_PRIORITY PPC_BITMASK(24,31) +#define IODA2_IVT_P PPC_BITMASK(39,39) +#define IODA2_IVT_Q PPC_BITMASK(47,47) +#define IODA2_IVT_PE PPC_BITMASK(48,63) + +/* TVT */ +#define IODA2_TVT_TABLE_ADDR PPC_BITMASK(0,47) +#define IODA2_TVT_NUM_LEVELS PPC_BITMASK(48,50) +#define IODA2_TVE_1_LEVEL 0 +#define IODA2_TVE_2_LEVELS 1 +#define IODA2_TVE_3_LEVELS 2 +#define IODA2_TVE_4_LEVELS 3 +#define IODA2_TVE_5_LEVELS 4 +#define IODA2_TVT_TCE_TABLE_SIZE PPC_BITMASK(51,55) +#define IODA2_TVT_IO_PSIZE PPC_BITMASK(59,63) + +/* PESTA */ +#define IODA2_PESTA_MMIO_FROZEN PPC_BIT(0) + +/* PESTB */ +#define IODA2_PESTB_DMA_STOPPED PPC_BIT(0) + +/* M32DT */ +#define IODA2_M32DT_PE PPC_BITMASK(8,15) + +/* M64BT */ +#define IODA2_M64BT_ENABLE PPC_BIT(0) +#define IODA2_M64BT_SINGLE_PE PPC_BIT(1) +#define IODA2_M64BT_BASE PPC_BITMASK(2,31) +#define IODA2_M64BT_MASK PPC_BITMASK(34,63) +#define IODA2_M64BT_SINGLE_BASE PPC_BITMASK(2,26) +#define IODA2_M64BT_PE_HI PPC_BITMASK(27,31) +#define IODA2_M64BT_SINGLE_MASK PPC_BITMASK(34,58) +#define IODA2_M64BT_PE_LOW PPC_BITMASK(59,63) + +/* + * IODA2 in-memory tables + */ + +/* PEST + * + * 2x8 bytes entries, PEST0 and PEST1 + */ + +#define IODA2_PEST0_MMIO_CAUSE PPC_BIT(2) +#define IODA2_PEST0_CFG_READ PPC_BIT(3) +#define IODA2_PEST0_CFG_WRITE PPC_BIT(4) +#define IODA2_PEST0_TTYPE PPC_BITMASK(5,7) +#define PEST_TTYPE_DMA_WRITE 0 +#define PEST_TTYPE_MSI 1 +#define PEST_TTYPE_DMA_READ 2 +#define PEST_TTYPE_DMA_READ_RESP 3 +#define PEST_TTYPE_MMIO_LOAD 4 +#define PEST_TTYPE_MMIO_STORE 5 +#define PEST_TTYPE_OTHER 7 +#define IODA2_PEST0_CA_RETURN PPC_BIT(8) +#define IODA2_PEST0_UTL_RTOS_TIMEOUT PPC_BIT(8) /* Same bit as CA return */ +#define IODA2_PEST0_UR_RETURN PPC_BIT(9) +#define IODA2_PEST0_UTL_NONFATAL PPC_BIT(10) +#define IODA2_PEST0_UTL_FATAL PPC_BIT(11) +#define IODA2_PEST0_PARITY_UE PPC_BIT(13) +#define IODA2_PEST0_UTL_CORRECTABLE PPC_BIT(14) +#define IODA2_PEST0_UTL_INTERRUPT PPC_BIT(15) +#define IODA2_PEST0_MMIO_XLATE PPC_BIT(16) +#define IODA2_PEST0_IODA2_ERROR PPC_BIT(16) /* Same bit as MMIO xlate */ +#define IODA2_PEST0_TCE_PAGE_FAULT PPC_BIT(18) +#define IODA2_PEST0_TCE_ACCESS_FAULT PPC_BIT(19) +#define IODA2_PEST0_DMA_RESP_TIMEOUT PPC_BIT(20) +#define IODA2_PEST0_AIB_SIZE_INVALID PPC_BIT(21) +#define IODA2_PEST0_LEM_BIT PPC_BITMASK(26,31) +#define IODA2_PEST0_RID PPC_BITMASK(32,47) +#define IODA2_PEST0_MSI_DATA PPC_BITMASK(48,63) + +#define IODA2_PEST1_FAIL_ADDR PPC_BITMASK(3,63) + + +#endif /* __PHB3_REGS_H */ diff --git a/roms/skiboot/include/phb3.h b/roms/skiboot/include/phb3.h new file mode 100644 index 000000000..c8a605f11 --- /dev/null +++ b/roms/skiboot/include/phb3.h @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __PHB3_H +#define __PHB3_H + +#include <interrupts.h> + +/* + * Memory map + * + * In addition to the 4K MMIO registers window, the PBCQ will + * forward down one or two large MMIO regions for use by the + * PHB. + * + * We try to use the largest MMIO window for the M64 space and + * the smallest for the M32 space, but we require at least 2G + * of M32, otherwise we carve it out of M64. + */ + +#define M32_PCI_START 0x080000000 /* Offset of the actual M32 window in PCI */ +#define M32_PCI_SIZE 0x80000000ul /* Size for M32 */ + +/* + * Interrupt map. + * + * Each PHB supports 2K interrupt sources, which is shared by + * LSI and MSI. With default configuration, MSI would use range + * [0, 0x7f7] and LSI would use [0x7f8, 0x7ff]. The interrupt + * source should be combined with IRSN to form final hardware + * IRQ. + */ +#define PHB3_MSI_IRQ_MIN 0x000 +#define PHB3_MSI_IRQ_COUNT 0x7F8 +#define PHB3_MSI_IRQ_MAX (PHB3_MSI_IRQ_MIN+PHB3_MSI_IRQ_COUNT-1) +#define PHB3_LSI_IRQ_MIN (PHB3_MSI_IRQ_COUNT) +#define PHB3_LSI_IRQ_COUNT 8 +#define PHB3_LSI_IRQ_MAX (PHB3_LSI_IRQ_MIN+PHB3_LSI_IRQ_COUNT-1) + +#define PHB3_MSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ + PHB3_MSI_IRQ_MIN) +#define PHB3_LSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ + PHB3_LSI_IRQ_MIN) +#define PHB3_IRQ_NUM(irq) (irq & 0x7FF) + +/* + * LSI interrupts + * + * The LSI interrupt block supports 8 interrupts. 4 of them are the + * standard PCIe INTA..INTB. The rest is for additional functions + * of the PHB + */ +#define PHB3_LSI_PCIE_INTA 0 +#define PHB3_LSI_PCIE_INTB 1 +#define PHB3_LSI_PCIE_INTC 2 +#define PHB3_LSI_PCIE_INTD 3 +#define PHB3_LSI_PCIE_INF 6 +#define PHB3_LSI_PCIE_ER 7 + +/* + * In-memory tables + * + * PHB3 requires a bunch of tables to be in memory instead of + * arrays inside the chip (unlike previous versions of the + * design). + * + * Some of them (IVT, etc...) will be provided by the OS via an + * OPAL call, not only not all of them, we also need to make sure + * some like PELT-V exist before we do our internal slot probing + * or bad thing would happen on error (the whole PHB would go into + * Fatal error state). + * + * So we maintain a set of tables internally for those mandatory + * ones within our core memory. They are fairly small. They can + * still be replaced by OS provided ones via OPAL APIs (and reset + * to the internal ones) so the OS can provide node local allocation + * for better performances. + * + * All those tables have to be naturally aligned + */ + +/* RTT Table : 128KB - Maps RID to PE# + * + * Entries are 2 bytes indexed by PCIe RID + */ +#define RTT_TABLE_ENTRIES 0x10000 +#define RTT_TABLE_SIZE 0x20000 + +/* IVT Table : MSI Interrupt vectors * state. + * + * We're sure that simics has 16-bytes IVE, totally 32KB. + * However the real HW possiblly has 128-bytes IVE, totally 256KB. + */ +#define IVT_TABLE_ENTRIES 0x800 + +/* Default to 128-bytes IVEs, uncomment that to force it back to 16-bytes */ +//#define IVT_TABLE_IVE_16B + +#ifdef IVT_TABLE_IVE_16B +#define IVT_TABLE_SIZE 0x8000 +#define IVT_TABLE_STRIDE 2 /* double-words */ +#else +#define IVT_TABLE_SIZE 0x40000 +#define IVT_TABLE_STRIDE 16 /* double-words */ +#endif + +/* PELT-V Table : 8KB - Maps PE# to PE# dependencies + * + * 256 entries of 256 bits (32 bytes) each + */ +#define PELTV_TABLE_SIZE 0x2000 + +/* PEST Table : 4KB - PE state table + * + * 256 entries of 16 bytes each containing state bits for each PE + * + * AFAIK: This acts as a backup for an on-chip cache and shall be + * accessed via the indirect IODA table access registers only + */ +#define PEST_TABLE_SIZE 0x1000 + +/* RBA Table : 256 bytes - Reject Bit Array + * + * 2048 interrupts, 1 bit each, indiates the reject state of interrupts + */ +#define RBA_TABLE_SIZE 0x100 + +/* + * Maximal supported PE# in PHB3. We probably probe it from EEH + * capability register later. + */ +#define PHB3_MAX_PE_NUM 256 +#define PHB3_RESERVED_PE_NUM 255 + +/* + * PHB3 PCI slot state. When you're going to apply any + * changes here, please make sure the base state isn't + * conflicting with those defined in pci-slot.h + */ +#define PHB3_SLOT_NORMAL PCI_SLOT_STATE_NORMAL +#define PHB3_SLOT_LINK PCI_SLOT_STATE_LINK +#define PHB3_SLOT_LINK_START (PHB3_SLOT_LINK + 1) +#define PHB3_SLOT_LINK_WAIT_ELECTRICAL (PHB3_SLOT_LINK + 2) +#define PHB3_SLOT_LINK_WAIT (PHB3_SLOT_LINK + 3) +#define PHB3_SLOT_HRESET PCI_SLOT_STATE_HRESET +#define PHB3_SLOT_HRESET_START (PHB3_SLOT_HRESET + 1) +#define PHB3_SLOT_HRESET_DELAY (PHB3_SLOT_HRESET + 2) +#define PHB3_SLOT_HRESET_DELAY2 (PHB3_SLOT_HRESET + 3) +#define PHB3_SLOT_FRESET PCI_SLOT_STATE_FRESET +#define PHB3_SLOT_FRESET_START (PHB3_SLOT_FRESET + 1) +#define PHB3_SLOT_FRESET_ASSERT_DELAY (PHB3_SLOT_FRESET + 2) +#define PHB3_SLOT_FRESET_DEASSERT_DELAY (PHB3_SLOT_FRESET + 3) +#define PHB3_SLOT_CRESET PCI_SLOT_STATE_CRESET +#define PHB3_SLOT_CRESET_START (PHB3_SLOT_CRESET + 1) +#define PHB3_SLOT_CRESET_WAIT_CQ (PHB3_SLOT_CRESET + 2) +#define PHB3_SLOT_CRESET_REINIT (PHB3_SLOT_CRESET + 3) +#define PHB3_SLOT_CRESET_FRESET (PHB3_SLOT_CRESET + 4) + +/* + * PHB3 error descriptor. Errors from all components (PBCQ, PHB) + * will be cached to PHB3 instance. However, PBCQ errors would + * have higher priority than those from PHB + */ +#define PHB3_ERR_SRC_NONE 0 +#define PHB3_ERR_SRC_PBCQ 1 +#define PHB3_ERR_SRC_PHB 2 + +#define PHB3_ERR_CLASS_NONE 0 +#define PHB3_ERR_CLASS_DEAD 1 +#define PHB3_ERR_CLASS_FENCED 2 +#define PHB3_ERR_CLASS_ER 3 +#define PHB3_ERR_CLASS_INF 4 +#define PHB3_ERR_CLASS_LAST 5 + +struct phb3_err { + uint32_t err_src; + uint32_t err_class; + uint32_t err_bit; +}; + +/* Link timeouts, increments of 100ms */ +#define PHB3_LINK_WAIT_RETRIES 20 +#define PHB3_LINK_ELECTRICAL_RETRIES 20 + +/* PHB3 flags */ +#define PHB3_AIB_FENCED (1 << 0) +#define PHB3_CFG_USE_ASB (1 << 1) +#define PHB3_CFG_BLOCKED (1 << 2) +#define PHB3_CAPP_RECOVERY (1 << 3) +#define PHB3_CAPP_DISABLING (1 << 4) + +struct phb3 { + unsigned int index; /* 0..2 index inside P8 */ + unsigned int flags; + unsigned int chip_id; /* Chip ID (== GCID on P8) */ + bool broken; + unsigned int rev; /* 00MMmmmm */ +#define PHB3_REV_MURANO_DD10 0xa30001 +#define PHB3_REV_VENICE_DD10 0xa30002 +#define PHB3_REV_MURANO_DD20 0xa30003 +#define PHB3_REV_MURANO_DD21 0xa30004 +#define PHB3_REV_VENICE_DD20 0xa30005 +#define PHB3_REV_NAPLES_DD10 0xb30001 + void *regs; + uint64_t pe_xscom; /* XSCOM bases */ + uint64_t pci_xscom; + uint64_t spci_xscom; + uint64_t mm0_base; /* Full MM window to PHB */ + uint64_t mm0_size; /* '' '' '' */ + uint64_t mm1_base; /* Full MM window to PHB */ + uint64_t mm1_size; /* '' '' '' */ + uint32_t base_msi; + uint32_t base_lsi; + + /* SkiBoot owned in-memory tables */ + uint64_t tbl_rtt; + uint64_t tbl_peltv; + uint64_t tbl_pest; + uint64_t tbl_ivt; + uint64_t tbl_rba; + + bool skip_perst; /* Skip first perst */ + bool has_link; + int64_t ecap; /* cached PCI-E cap offset */ + int64_t aercap; /* cached AER ecap offset */ + const __be64 *lane_eq; + unsigned int max_link_speed; + uint32_t no_ecrc_devs; + + uint16_t rte_cache[RTT_TABLE_ENTRIES]; + uint8_t peltv_cache[PELTV_TABLE_SIZE]; + uint64_t lxive_cache[8]; + uint64_t ive_cache[IVT_TABLE_ENTRIES]; + uint64_t tve_cache[512]; + uint64_t m32d_cache[256]; + uint64_t m64b_cache[16]; + uint64_t nfir_cache; /* Used by complete reset */ + bool err_pending; + struct phb3_err err; + + struct phb phb; +}; + +#define PHB3_IS_NAPLES(p) ((p)->rev == PHB3_REV_NAPLES_DD10) + +/* + * Venice/Murano have one CAPP unit, that can be attached to PHB0,1 or 2. + * Naples has two CAPP units: CAPP0 attached to PHB0, CAPP1 attached to PHB1. + */ +#define PHB3_CAPP_MAX_PHB_INDEX(p) (PHB3_IS_NAPLES(p) ? 1 : 2) + +#define PHB3_CAPP_REG_OFFSET(p) \ + ((p)->index && PHB3_IS_NAPLES(p) ? CAPP1_REG_OFFSET : 0x0) + +static inline struct phb3 *phb_to_phb3(struct phb *phb) +{ + return container_of(phb, struct phb3, phb); +} + +static inline uint64_t phb3_read_reg_asb(struct phb3 *p, uint64_t offset) +{ + uint64_t val; + + xscom_write(p->chip_id, p->spci_xscom, offset); + xscom_read(p->chip_id, p->spci_xscom + 0x2, &val); + + return val; +} + +static inline void phb3_write_reg_asb(struct phb3 *p, + uint64_t offset, uint64_t val) +{ + xscom_write(p->chip_id, p->spci_xscom, offset); + xscom_write(p->chip_id, p->spci_xscom + 0x2, val); +} + +static inline bool phb3_err_pending(struct phb3 *p) +{ + return p->err_pending; +} + +static inline void phb3_set_err_pending(struct phb3 *p, bool pending) +{ + if (!pending) { + p->err.err_src = PHB3_ERR_SRC_NONE; + p->err.err_class = PHB3_ERR_CLASS_NONE; + p->err.err_bit = -1; + } + + p->err_pending = pending; +} + +#endif /* __PHB3_H */ diff --git a/roms/skiboot/include/phb4-capp.h b/roms/skiboot/include/phb4-capp.h new file mode 100644 index 000000000..789b6e88e --- /dev/null +++ b/roms/skiboot/include/phb4-capp.h @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __PHB4_CAPP_H +#define __PHB4_CAPP_H + +#define CAPP_SNP_ARRAY_WRITE_REG 0x2010841 /* Satellite 2 */ +#define CAPP_SNP_ARRAY_ADDR_REG 0x2010828 +#define CAPP_APC_MASTER_ARRAY_ADDR_REG 0x201082A +#define CAPP_APC_MASTER_ARRAY_WRITE_REG 0x2010842 /* Satellite 2 */ + +#define CAPP_FIR 0x2010800 +#define CAPP_FIR_CLEAR 0x2010801 +#define CAPP_FIR_MASK 0x2010803 +#define CAPP_FIR_ACTION0 0x2010806 +#define CAPP_FIR_ACTION1 0x2010807 +#define CAPP_SNOOP_ERR_RTP 0x201080A +#define CAPP_APC_MASTER_ERR_RPT 0x201080B +#define CAPP_TRANSPORT_ERR_RPT 0x201080C +#define CAPP_TLBI_ERR_RPT 0x201080D +#define CAPP_ERR_STATUS_CTRL 0x201080E +#define FLUSH_SUE_STATE_MAP 0x201080F +#define CAPP_ERR_RPT_CLR 0x2010813 +#define APC_MASTER_PB_CTRL 0x2010818 +#define APC_MASTER_CAPI_CTRL 0x2010819 +#define LCO_MASTER_TARGET 0x2010821 +#define EPOCH_RECOVERY_TIMERS_CTRL 0x201082C +#define SNOOP_CAPI_CONFIG 0x201081A +#define SNOOP_CONTROL 0x201081B +#define TRANSPORT_CONTROL 0x201081C +#define CAPP_TB 0x2010826 +#define CAPP_TFMR 0x2010827 +#define FLUSH_CPIG_STATE_MAP 0x2010820 +#define FLUSH_SUE_UOP1 0x2010843 /* Satellite 2 */ +#define APC_FSM_READ_MASK 0x2010823 +#define XPT_FSM_RMM 0x2010831 + +/* CAPP0 attached to PHB0(PEC0 - single port) + * CAPP1 attached to PHB3(PEC2 - single or dual port) + */ +#define CAPP0_PHB_INDEX 0 +#define CAPP1_PHB_INDEX 3 + +/* SCOM address Base (Ring = ‘0010’b) + * CAPP Unit Satellite SCOM address Base + * CAPP 0 S1 (sat = ‘0000’b) x02010800 + * CAPP 0 S2 (sat = ‘0001’b) x02010840 + * CAPP 1 S1 (sat = ‘0000’b) x04010800 + * CAPP 1 S2 (sat = ‘0001’b) x04010840 + */ +#define CAPP1_REG_OFFSET 0x2000000 + +#define PHB4_CAPP_REG_OFFSET(p) ((p)->index == 0 ? 0x0 : CAPP1_REG_OFFSET) + +#define CAPP_MIN_STQ_ENGINES 0x00000001 +#define CAPP_MAX_STQ_ENGINES 0x00000002 +#define CAPP_MIN_DMA_READ_ENGINES 0x00000100 +#define CAPP_MAX_DMA_READ_ENGINES 0x00000200 + +#endif /* __PHB4_CAPP_H */ diff --git a/roms/skiboot/include/phb4-regs.h b/roms/skiboot/include/phb4-regs.h new file mode 100644 index 000000000..b4a94c056 --- /dev/null +++ b/roms/skiboot/include/phb4-regs.h @@ -0,0 +1,514 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __PHB4_REGS_H +#define __PHB4_REGS_H + +/* + * PHB registers + */ + +/* PHB Fundamental register set A */ +/* phb4_spec_036.pdf, page 80, "5.4.1 ETU/RSB HV Register Address Map" */ +/* FIXME: check these (phb3 currently below) */ +#define PHB_LSI_SOURCE_ID 0x100 +#define PHB_LSI_SRC_ID PPC_BITMASK(4,12) +#define PHB_DMA_CHAN_STATUS 0x110 +#define PHB_DMA_CHAN_ANY_ERR PPC_BIT(27) +#define PHB_DMA_CHAN_ANY_ERR1 PPC_BIT(28) +#define PHB_DMA_CHAN_ANY_FREEZE PPC_BIT(29) +#define PHB_CPU_LOADSTORE_STATUS 0x120 +#define PHB_CPU_LS_ANY_ERR PPC_BIT(27) +#define PHB_CPU_LS_ANY_ERR1 PPC_BIT(28) +#define PHB_CPU_LS_ANY_FREEZE PPC_BIT(29) +#define PHB_CONFIG_DATA 0x130 +#define PHB_LOCK0 0x138 +#define PHB_CONFIG_ADDRESS 0x140 +#define PHB_CA_ENABLE PPC_BIT(0) +#define PHB_CA_STATUS PPC_BITMASK(1,3) +#define PHB_CA_BUS PPC_BITMASK(4,11) +#define PHB_CA_DEV PPC_BITMASK(12,16) +#define PHB_CA_FUNC PPC_BITMASK(17,19) +#define PHB_CA_BDFN PPC_BITMASK(4,19) /* bus,dev,func */ +#define PHB_CA_REG PPC_BITMASK(20,31) +#define PHB_CA_PE PPC_BITMASK(39,47) +#define PHB_LOCK1 0x148 +#define PHB_PHB4_CONFIG 0x160 +#define PHB_PHB4C_32BIT_MSI_EN PPC_BIT(8) +#define PHB_PHB4C_64BIT_MSI_EN PPC_BIT(14) +#define PHB_RTT_BAR 0x168 +#define PHB_RTT_BAR_ENABLE PPC_BIT(0) +#define PHB_RTT_BASE_ADDRESS PPC_BITMASK(8,46) +#define PHB_PELTV_BAR 0x188 +#define PHB_PELTV_BAR_ENABLE PPC_BIT(0) +#define PHB_PELTV_BASE_ADDRESS PPC_BITMASK(8,50) +#define PHB_M32_START_ADDR 0x1a0 +#define PHB_PEST_BAR 0x1a8 +#define PHB_PEST_BAR_ENABLE PPC_BIT(0) +#define PHB_PEST_BASE_ADDRESS PPC_BITMASK(8,51) +#define PHB_ASN_CMPM 0x1c0 +#define PHB_ASN_CMPM_ENABLE PPC_BIT(63) +#define PHB_CAPI_CMPM 0x1c8 +#define PHB_CAPI_CMPM_ENABLE PPC_BIT(63) +#define PHB_M64_AOMASK 0x1d0 +#define PHB_M64_UPPER_BITS 0x1f0 +#define PHB_NXLATE_PREFIX 0x1f8 +#define PHB_DMA_READ_WRITE_SYNC 0x200 +#define PHB_DMA_READ_SYNC_START PPC_BIT(0) +#define PHB_DMA_READ_SYNC_COMPLETE PPC_BIT(1) +#define PHB_DMA_WRITE_SYNC_START PPC_BIT(2) /* PHB5 */ +#define PHB_DMA_WRITE_SYNC_COMPLETE PPC_BIT(3) /* PHB5 */ +#define PHB_RTC_INVALIDATE 0x208 +#define PHB_RTC_INVALIDATE_ALL PPC_BIT(0) +#define PHB_RTC_INVALIDATE_RID PPC_BITMASK(16,31) +#define PHB_TCE_KILL 0x210 +#define PHB_TCE_KILL_ALL PPC_BIT(0) +#define PHB_TCE_KILL_PE PPC_BIT(1) +#define PHB_TCE_KILL_ONE PPC_BIT(2) +#define PHB_TCE_KILL_PSEL PPC_BIT(3) +#define PHB_TCE_KILL_64K 0x1000 /* Address override */ +#define PHB_TCE_KILL_2M 0x2000 /* Address override */ +#define PHB_TCE_KILL_1G 0x3000 /* Address override */ +#define PHB_TCE_KILL_PENUM PPC_BITMASK(55,63) +#define PHB_TCE_SPEC_CTL 0x218 +#define PHB_IODA_ADDR 0x220 +#define PHB_IODA_AD_AUTOINC PPC_BIT(0) +#define PHB_IODA_AD_TSEL PPC_BITMASK(11,15) +#define PHB_IODA_AD_MIST_PWV PPC_BITMASK(28,31) +#define PHB_IODA_AD_TADR PPC_BITMASK(54,63) +#define PHB_IODA_DATA0 0x228 +#define PHB_PHB4_GEN_CAP 0x250 +#define PHB_PHB4_TCE_CAP 0x258 +#define PHB_PHB4_IRQ_CAP 0x260 +#define PHB_PHB4_EEH_CAP 0x268 +#define PHB_PAPR_ERR_INJ_CTL 0x2b0 +#define PHB_PAPR_ERR_INJ_CTL_INB PPC_BIT(0) +#define PHB_PAPR_ERR_INJ_CTL_OUTB PPC_BIT(1) +#define PHB_PAPR_ERR_INJ_CTL_STICKY PPC_BIT(2) +#define PHB_PAPR_ERR_INJ_CTL_CFG PPC_BIT(3) +#define PHB_PAPR_ERR_INJ_CTL_RD PPC_BIT(4) +#define PHB_PAPR_ERR_INJ_CTL_WR PPC_BIT(5) +#define PHB_PAPR_ERR_INJ_CTL_FREEZE PPC_BIT(6) +#define PHB_PAPR_ERR_INJ_ADDR 0x2b8 +#define PHB_PAPR_ERR_INJ_ADDR_MMIO PPC_BITMASK(16,63) +#define PHB_PAPR_ERR_INJ_MASK 0x2c0 +#define PHB_PAPR_ERR_INJ_MASK_CFG PPC_BITMASK(4,11) +#define PHB_PAPR_ERR_INJ_MASK_CFG_ALL PPC_BITMASK(4,19) +#define PHB_PAPR_ERR_INJ_MASK_MMIO PPC_BITMASK(16,63) +#define PHB_ETU_ERR_SUMMARY 0x2c8 +#define PHB_INT_NOTIFY_ADDR 0x300 +#define PHB_INT_NOTIFY_ADDR_64K PPC_BIT(1) /* PHB5 */ +#define PHB_INT_NOTIFY_INDEX 0x308 + +#define PHB_VERSION 0x800 +#define PHB_CTRLR 0x810 +#define PHB_CTRLR_IRQ_PQ_DISABLE PPC_BIT(9) /* PHB5 */ +#define PHB_CTRLR_IRQ_ABT_MODE PPC_BIT(10) /* PHB5 */ +#define PHB_CTRLR_IRQ_PGSZ_64K PPC_BIT(11) +#define PHB_CTRLR_IRQ_STORE_EOI PPC_BIT(12) +#define PHB_CTRLR_MMIO_RD_STRICT PPC_BIT(13) +#define PHB_CTRLR_MMIO_EEH_DISABLE PPC_BIT(14) +#define PHB_CTRLR_CFG_EEH_BLOCK PPC_BIT(15) +#define PHB_CTRLR_FENCE_LNKILL_DIS PPC_BIT(16) +#define PHB_CTRLR_TVT_ADDR_SEL PPC_BITMASK(17,19) +#define TVT_2_PER_PE 0 +#define TVT_4_PER_PE 1 +#define TVT_8_PER_PE 2 +#define TVT_16_PER_PE 3 +#define PHB_CTRLR_TCE_CLB_DISABLE PPC_BIT(21) +#define PHB_CTRLR_DMA_RD_SPACING PPC_BITMASK(28,31) +#define PHB_AIB_FENCE_CTRL 0x860 +#define PHB_TCE_TAG_ENABLE 0x868 +#define PHB_TCE_WATERMARK 0x870 +#define PHB_TIMEOUT_CTRL1 0x878 +#define PHB_TIMEOUT_CTRL2 0x880 +#define PHB_Q_DMA_R 0x888 +#define PHB_Q_DMA_R_QUIESCE_DMA PPC_BIT(0) +#define PHB_Q_DMA_R_AUTORESET PPC_BIT(1) +#define PHB_Q_DMA_R_DMA_RESP_STATUS PPC_BIT(4) +#define PHB_Q_DMA_R_MMIO_RESP_STATUS PPC_BIT(5) +#define PHB_Q_DMA_R_TCE_RESP_STATUS PPC_BIT(6) +#define PHB_Q_DMA_R_TCE_KILL_STATUS PPC_BIT(7) +#define PHB_TCE_TAG_STATUS 0x908 + +/* FIR & Error registers */ +#define PHB_LEM_FIR_ACCUM 0xc00 +#define PHB_LEM_FIR_AND_MASK 0xc08 +#define PHB_LEM_FIR_OR_MASK 0xc10 +#define PHB_LEM_ERROR_MASK 0xc18 +#define PHB_LEM_ERROR_AND_MASK 0xc20 +#define PHB_LEM_ERROR_OR_MASK 0xc28 +#define PHB_LEM_ACTION0 0xc30 +#define PHB_LEM_ACTION1 0xc38 +#define PHB_LEM_WOF 0xc40 +#define PHB_ERR_STATUS 0xc80 +#define PHB_ERR1_STATUS 0xc88 +#define PHB_ERR_INJECT 0xc90 +#define PHB_ERR_LEM_ENABLE 0xc98 +#define PHB_ERR_IRQ_ENABLE 0xca0 +#define PHB_ERR_FREEZE_ENABLE 0xca8 +#define PHB_ERR_AIB_FENCE_ENABLE 0xcb0 +#define PHB_ERR_LOG_0 0xcc0 +#define PHB_ERR_LOG_1 0xcc8 +#define PHB_ERR_STATUS_MASK 0xcd0 +#define PHB_ERR1_STATUS_MASK 0xcd8 + +/* + * Instead of MMIO outbound, inboundA and inboundB in PHB3, + * PHB4 has TXE (outbound), RXE_ARB, RXE_MRG and RXE_TCE. + */ + +#define PHB_TXE_ERR_STATUS 0xd00 +#define PHB_TXE_ERR1_STATUS 0xd08 +#define PHB_TXE_ERR_INJECT 0xd10 +#define PHB_TXE_ERR_LEM_ENABLE 0xd18 +#define PHB_TXE_ERR_IRQ_ENABLE 0xd20 +#define PHB_TXE_ERR_FREEZE_ENABLE 0xd28 +#define PHB_TXE_ERR_AIB_FENCE_ENABLE 0xd30 +#define PHB_TXE_ERR_LOG_0 0xd40 +#define PHB_TXE_ERR_LOG_1 0xd48 +#define PHB_TXE_ERR_STATUS_MASK 0xd50 +#define PHB_TXE_ERR1_STATUS_MASK 0xd58 + +#define PHB_RXE_ARB_ERR_STATUS 0xd80 +#define PHB_RXE_ARB_ERR1_STATUS 0xd88 +#define PHB_RXE_ARB_ERR_INJECT 0xd90 +#define PHB_RXE_ARB_ERR_LEM_ENABLE 0xd98 +#define PHB_RXE_ARB_ERR_IRQ_ENABLE 0xda0 +#define PHB_RXE_ARB_ERR_FREEZE_ENABLE 0xda8 +#define PHB_RXE_ARB_ERR_AIB_FENCE_ENABLE 0xdb0 +#define PHB_RXE_ARB_ERR_LOG_0 0xdc0 +#define PHB_RXE_ARB_ERR_LOG_1 0xdc8 +#define PHB_RXE_ARB_ERR_STATUS_MASK 0xdd0 +#define PHB_RXE_ARB_ERR1_STATUS_MASK 0xdd8 + +#define PHB_RXE_MRG_ERR_STATUS 0xe00 +#define PHB_RXE_MRG_ERR1_STATUS 0xe08 +#define PHB_RXE_MRG_ERR_INJECT 0xe10 +#define PHB_RXE_MRG_ERR_LEM_ENABLE 0xe18 +#define PHB_RXE_MRG_ERR_IRQ_ENABLE 0xe20 +#define PHB_RXE_MRG_ERR_FREEZE_ENABLE 0xe28 +#define PHB_RXE_MRG_ERR_AIB_FENCE_ENABLE 0xe30 +#define PHB_RXE_MRG_ERR_LOG_0 0xe40 +#define PHB_RXE_MRG_ERR_LOG_1 0xe48 +#define PHB_RXE_MRG_ERR_STATUS_MASK 0xe50 +#define PHB_RXE_MRG_ERR1_STATUS_MASK 0xe58 + +#define PHB_RXE_TCE_ERR_STATUS 0xe80 +#define PHB_RXE_TCE_ERR1_STATUS 0xe88 +#define PHB_RXE_TCE_ERR_INJECT 0xe90 +#define PHB_RXE_TCE_ERR_LEM_ENABLE 0xe98 +#define PHB_RXE_TCE_ERR_IRQ_ENABLE 0xea0 +#define PHB_RXE_TCE_ERR_FREEZE_ENABLE 0xea8 +#define PHB_RXE_TCE_ERR_AIB_FENCE_ENABLE 0xeb0 +#define PHB_RXE_TCE_ERR_LOG_0 0xec0 +#define PHB_RXE_TCE_ERR_LOG_1 0xec8 +#define PHB_RXE_TCE_ERR_STATUS_MASK 0xed0 +#define PHB_RXE_TCE_ERR1_STATUS_MASK 0xed8 + +/* Performance monitor & Debug registers */ +#define PHB_TRACE_CONTROL 0xf80 +#define PHB_PERFMON_CONFIG 0xf88 +#define PHB_PERFMON_CTR0 0xf90 +#define PHB_PERFMON_CTR1 0xf98 +#define PHB_PERFMON_CTR2 0xfa0 +#define PHB_PERFMON_CTR3 0xfa8 + +/* Root complex config space memory mapped */ +#define PHB_RC_CONFIG_BASE 0x1000 +#define PHB_RC_CONFIG_SIZE 0x800 + +/* PHB4 REGB registers */ + +/* PBL core */ +#define PHB_PBL_CONTROL 0x1800 +#define PHB_PBL_TIMEOUT_CTRL 0x1810 +#define PHB_PBL_NPTAG_ENABLE 0x1820 +#define PHB_PBL_NBW_CMP_MASK 0x1830 +#define PHB_PBL_NBW_MASK_ENABLE PPC_BIT(63) +#define PHB_PBL_SYS_LINK_INIT 0x1838 +#define PHB_PBL_BUF_STATUS 0x1840 +#define PHB_PBL_ERR_STATUS 0x1900 +#define PHB_PBL_ERR1_STATUS 0x1908 +#define PHB_PBL_ERR_INJECT 0x1910 +#define PHB_PBL_ERR_INF_ENABLE 0x1920 +#define PHB_PBL_ERR_ERC_ENABLE 0x1928 +#define PHB_PBL_ERR_FAT_ENABLE 0x1930 +#define PHB_PBL_ERR_LOG_0 0x1940 +#define PHB_PBL_ERR_LOG_1 0x1948 +#define PHB_PBL_ERR_STATUS_MASK 0x1950 +#define PHB_PBL_ERR1_STATUS_MASK 0x1958 + +/* PCI-E stack */ +#define PHB_PCIE_SCR 0x1A00 +#define PHB_PCIE_SCR_SLOT_CAP PPC_BIT(15) +#define PHB_PCIE_SCR_MAXLINKSPEED PPC_BITMASK(32,35) + + +#define PHB_PCIE_CRESET 0x1A10 +#define PHB_PCIE_CRESET_CFG_CORE PPC_BIT(0) +#define PHB_PCIE_CRESET_TLDLP PPC_BIT(1) +#define PHB_PCIE_CRESET_PBL PPC_BIT(2) +#define PHB_PCIE_CRESET_PERST_N PPC_BIT(3) +#define PHB_PCIE_CRESET_PIPE_N PPC_BIT(4) + + +#define PHB_PCIE_HOTPLUG_STATUS 0x1A20 +#define PHB_PCIE_HPSTAT_PRESENCE PPC_BIT(10) + +#define PHB_PCIE_DLP_TRAIN_CTL 0x1A40 +#define PHB_PCIE_DLP_LINK_WIDTH PPC_BITMASK(30,35) +#define PHB_PCIE_DLP_LINK_SPEED PPC_BITMASK(36,39) +#define PHB_PCIE_DLP_LTSSM_TRC PPC_BITMASK(24,27) +#define PHB_PCIE_DLP_LTSSM_RESET 0 +#define PHB_PCIE_DLP_LTSSM_DETECT 1 +#define PHB_PCIE_DLP_LTSSM_POLLING 2 +#define PHB_PCIE_DLP_LTSSM_CONFIG 3 +#define PHB_PCIE_DLP_LTSSM_L0 4 +#define PHB_PCIE_DLP_LTSSM_REC 5 +#define PHB_PCIE_DLP_LTSSM_L1 6 +#define PHB_PCIE_DLP_LTSSM_L2 7 +#define PHB_PCIE_DLP_LTSSM_HOTRESET 8 +#define PHB_PCIE_DLP_LTSSM_DISABLED 9 +#define PHB_PCIE_DLP_LTSSM_LOOPBACK 10 +#define PHB_PCIE_DLP_TL_LINKACT PPC_BIT(23) +#define PHB_PCIE_DLP_DL_PGRESET PPC_BIT(22) +#define PHB_PCIE_DLP_TRAINING PPC_BIT(20) +#define PHB_PCIE_DLP_INBAND_PRESENCE PPC_BIT(19) +#define PHB_PCIE_DLP_SYS_DISABLEDETECT PPC_BIT(12) +#define PHB_PCIE_DLP_CTL 0x1A78 +#define PHB_PCIE_DLP_CTL_BYPASS_PH2 PPC_BIT(4) +#define PHB_PCIE_DLP_CTL_BYPASS_PH3 PPC_BIT(5) +#define PHB_PCIE_DLP_CTL_SFC_DISABLE PPC_BIT(60) + +#define PHB_PCIE_DLP_TRWCTL 0x1A80 +#define PHB_PCIE_DLP_TRWCTL_EN PPC_BIT(0) + +#define PHB_PCIE_DLP_ERRLOG1 0x1AA0 +#define PHB_PCIE_DLP_ERRLOG2 0x1AA8 +#define PHB_PCIE_DLP_ERR_STATUS 0x1AB0 +#define PHB_PCIE_DLP_LANE_ERR PPC_BITMASK(0,15) +#define PHB_PCIE_DLP_ERR_COUNTERS 0x1AB8 +#define PHB_PCIE_DLP_RX_ERR_CNT PPC_BITMASK(16,23) + +#define PHB_PCIE_LANE_EQ_CNTL0 0x1AD0 +#define PHB_PCIE_LANE_EQ_CNTL1 0x1AD8 +#define PHB_PCIE_LANE_EQ_CNTL2 0x1AE0 +#define PHB_PCIE_LANE_EQ_CNTL3 0x1AE8 +#define PHB_PCIE_LANE_EQ_CNTL40 0x1AF0 +#define PHB_PCIE_LANE_EQ_CNTL41 0x1AF8 +#define PHB_PCIE_LANE_EQ_CNTL50 0x1B00 +#define PHB_PCIE_LANE_EQ_CNTL51 0x1B08 +#define PHB_PCIE_TRACE_CTRL 0x1B20 +#define PHB_PCIE_MISC_STRAP 0x1B30 +#define PHB_PCIE_PDL_PHY_EQ_CNTL 0x1B38 + +/* Error */ +#define PHB_REGB_ERR_STATUS 0x1C00 +#define PHB_REGB_ERR1_STATUS 0x1C08 +#define PHB_REGB_ERR_INJECT 0x1C10 +#define PHB_REGB_ERR_INF_ENABLE 0x1C20 +#define PHB_REGB_ERR_ERC_ENABLE 0x1C28 +#define PHB_REGB_ERR_FAT_ENABLE 0x1C30 +#define PHB_REGB_ERR_LOG_0 0x1C40 +#define PHB_REGB_ERR_LOG_1 0x1C48 +#define PHB_REGB_ERR_STATUS_MASK 0x1C50 +#define PHB_REGB_ERR1_STATUS_MASK 0x1C58 + +/* + * PHB4 xscom address defines + */ + +/* Nest base registers */ +#define XPEC_NEST_PBCQ_HW_CONFIG 0x0 +#define XPEC_NEST_PBCQ_HW_CONFIG_PBINIT PPC_BIT(12) +#define XPEC_NEST_PBCQ_HW_CONFIG_CH_STR PPC_BIT(33) +#define XPEC_NEST_PBCQ_HW_CONFIG_DIS_NODAL PPC_BIT(50) +#define XPEC_NEST_PBCQ_HW_CONFIG_DIS_RNNN PPC_BIT(52) +#define XPEC_NEST_CAPP_CNTL 0x7 +#define XPEC_NEST_READ_STACK_OVERRIDE 0x8 + +/* Nest base per-stack registers */ +#define XPEC_NEST_STK_PCI_NFIR 0x0 +#define XPEC_NEST_STK_PCI_NFIR_CXA_PE_CAPP PPC_BIT(24) +#define XPEC_NEST_STK_PCI_NFIR_CLR 0x1 +#define XPEC_NEST_STK_PCI_NFIR_SET 0x2 +#define XPEC_NEST_STK_PCI_NFIR_MSK 0x3 +#define XPEC_NEST_STK_PCI_NFIR_MSK_CLR 0x4 +#define XPEC_NEST_STK_PCI_NFIR_MSK_SET 0x5 +#define XPEC_NEST_STK_PCI_NFIR_ACTION0 0x6 +#define XPEC_NEST_STK_PCI_NFIR_ACTION1 0x7 +#define XPEC_NEST_STK_PCI_NFIR_WOF 0x8 +#define XPEC_NEST_STK_ERR_RPT0 0xa +#define XPEC_NEST_STK_ERR_RPT1 0xb +#define XPEC_NEST_STK_PBCQ_STAT 0xc +#define XPEC_NEST_STK_PBCQ_MODE 0xd +#define XPEC_NEST_STK_PBCQ_MODE_P2P PPC_BIT(0) +#define XPEC_NEST_STK_MMIO_BAR0 0xe +#define XPEC_NEST_STK_MMIO_BAR0_MASK 0xf +#define XPEC_NEST_STK_MMIO_BAR1 0x10 +#define XPEC_NEST_STK_MMIO_BAR1_MASK 0x11 +#define XPEC_NEST_STK_PHB_REG_BAR 0x12 +#define XPEC_NEST_STK_IRQ_BAR 0x13 +#define XPEC_NEST_STK_BAR_EN 0x14 +#define XPEC_NEST_STK_BAR_EN_MMIO0 PPC_BIT(0) +#define XPEC_NEST_STK_BAR_EN_MMIO1 PPC_BIT(1) +#define XPEC_NEST_STK_BAR_EN_PHB PPC_BIT(2) +#define XPEC_NEST_STK_BAR_EN_INT PPC_BIT(3) +#define XPEC_NEST_STK_DATA_FREZ_TYPE 0x15 +#define XPEC_NEST_STK_TUNNEL_BAR 0x16 + +/* PCI base registers */ +#define XPEC_PCI_PBAIB_HW_CONFIG 0x0 +#define XPEC_PCI_CAPP_SEC_BAR 0x1 +#define XPEC_PCI_PRDSTKOVR 0x2 + +/* PCI base per-stack registers */ +#define XPEC_PCI_STK_PCI_FIR 0x0 +#define XPEC_PCI_STK_PCI_FIR_CLR 0x1 +#define XPEC_PCI_STK_PCI_FIR_SET 0x2 +#define XPEC_PCI_STK_PCI_FIR_MSK 0x3 +#define XPEC_PCI_STK_PCI_FIR_MSK_CLR 0x4 +#define XPEC_PCI_STK_PCI_FIR_MSK_SET 0x5 +#define XPEC_PCI_STK_PCI_FIR_ACTION0 0x6 +#define XPEC_PCI_STK_PCI_FIR_ACTION1 0x7 +#define XPEC_PCI_STK_PCI_FIR_WOF 0x8 +#define XPEC_PCI_STK_ETU_RESET 0xa +#define XPEC_PCI_STK_PBAIB_ERR_REPORT 0xb + +/* ETU XSCOM registers */ +#define XETU_HV_IND_ADDRESS 0x0 +#define XETU_HV_IND_ADDR_VALID PPC_BIT(0) +#define XETU_HV_IND_ADDR_4B PPC_BIT(1) +#define XETU_HV_IND_ADDR_AUTOINC PPC_BIT(2) +#define XETU_HV_IND_DATA 0x1 + + +/* PCI Chiplet Config Register */ +#define XPEC_PCI_CPLT_OFFSET 0x1000000ULL +#define XPEC_P9_PCI_CPLT_CONF1 0x000000000D000009ULL +#define XPEC_P9_PCI_IOVALID_MASK PPC_BITMASK(4, 6) +#define XPEC_P9_PCI_IOVALID_X16 PPC_BIT(4) +#define XPEC_P9_PCI_LANE_CFG PPC_BITMASK(10, 11) +#define XPEC_P10_PCI_CPLT_CONF1 0x0000000008000009ULL +#define XPEC_P10_PCI_LANE_CFG PPC_BITMASK(0, 1) + +/* + * IODA3 on-chip tables + */ + +#define IODA3_TBL_LIST 1 +#define IODA3_TBL_MIST 2 +#define IODA3_TBL_RCAM 5 +#define IODA3_TBL_MRT 6 +#define IODA3_TBL_PESTA 7 +#define IODA3_TBL_PESTB 8 +#define IODA3_TBL_TVT 9 +#define IODA3_TBL_TCAM 10 +#define IODA3_TBL_TDR 11 +#define IODA3_TBL_MBT 16 +#define IODA3_TBL_MDT 17 +#define IODA3_TBL_PEEV 20 + +/* LIST */ +#define IODA3_LIST_P PPC_BIT(6) +#define IODA3_LIST_Q PPC_BIT(7) +#define IODA3_LIST_STATE PPC_BIT(14) + +/* MIST */ +#define IODA3_MIST_P3 PPC_BIT(48 + 0) +#define IODA3_MIST_Q3 PPC_BIT(48 + 1) +#define IODA3_MIST_PE3 PPC_BITMASK(48 + 4, 48 + 15) + +/* TVT */ +#define IODA3_TVT_TABLE_ADDR PPC_BITMASK(0,47) +#define IODA3_TVT_NUM_LEVELS PPC_BITMASK(48,50) +#define IODA3_TVE_1_LEVEL 0 +#define IODA3_TVE_2_LEVELS 1 +#define IODA3_TVE_3_LEVELS 2 +#define IODA3_TVE_4_LEVELS 3 +#define IODA3_TVE_5_LEVELS 4 +#define IODA3_TVT_TCE_TABLE_SIZE PPC_BITMASK(51,55) +#define IODA3_TVT_NON_TRANSLATE_50 PPC_BIT(56) +#define IODA3_TVT_IO_PSIZE PPC_BITMASK(59,63) + +/* PESTA */ +#define IODA3_PESTA_MMIO_FROZEN PPC_BIT(0) +#define IODA3_PESTA_TRANS_TYPE PPC_BITMASK(5,7) +#define IODA3_PESTA_TRANS_TYPE_MMIOLOAD 0x4 +#define IODA3_PESTA_CA_CMPLT_TMT PPC_BIT(8) +#define IODA3_PESTA_UR PPC_BIT(9) + +/* PESTB */ +#define IODA3_PESTB_DMA_STOPPED PPC_BIT(0) + +/* MDT */ +/* FIXME: check this field with Eric and add a B, C and D */ +#define IODA3_MDT_PE_A PPC_BITMASK(0,15) +#define IODA3_MDT_PE_B PPC_BITMASK(16,31) +#define IODA3_MDT_PE_C PPC_BITMASK(32,47) +#define IODA3_MDT_PE_D PPC_BITMASK(48,63) + +/* MBT */ +#define IODA3_MBT0_ENABLE PPC_BIT(0) +#define IODA3_MBT0_TYPE PPC_BIT(1) +#define IODA3_MBT0_TYPE_M32 IODA3_MBT0_TYPE +#define IODA3_MBT0_TYPE_M64 0 +#define IODA3_MBT0_MODE PPC_BITMASK(2,3) +#define IODA3_MBT0_MODE_PE_SEG 0 +#define IODA3_MBT0_MODE_MDT 1 +#define IODA3_MBT0_MODE_SINGLE_PE 2 +#define IODA3_MBT0_SEG_DIV PPC_BITMASK(4,5) +#define IODA3_MBT0_SEG_DIV_MAX 0 +#define IODA3_MBT0_SEG_DIV_128 1 +#define IODA3_MBT0_SEG_DIV_64 2 +#define IODA3_MBT0_SEG_DIV_8 3 +#define IODA3_MBT0_MDT_COLUMN PPC_BITMASK(4,5) +#define IODA3_MBT0_BASE_ADDR PPC_BITMASK(8,51) + +#define IODA3_MBT1_ENABLE PPC_BIT(0) +#define IODA3_MBT1_MASK PPC_BITMASK(8,51) +#define IODA3_MBT1_SEG_BASE PPC_BITMASK(55,63) +#define IODA3_MBT1_SINGLE_PE_NUM PPC_BITMASK(55,63) + +/* + * IODA2 in-memory tables + */ + +/* PEST + * + * 2x8 bytes entries, PEST0 and PEST1 + */ + +#define IODA3_PEST0_MMIO_CAUSE PPC_BIT(2) +#define IODA3_PEST0_CFG_READ PPC_BIT(3) +#define IODA3_PEST0_CFG_WRITE PPC_BIT(4) +#define IODA3_PEST0_TTYPE PPC_BITMASK(5,7) +#define PEST_TTYPE_DMA_WRITE 0 +#define PEST_TTYPE_MSI 1 +#define PEST_TTYPE_DMA_READ 2 +#define PEST_TTYPE_DMA_READ_RESP 3 +#define PEST_TTYPE_MMIO_LOAD 4 +#define PEST_TTYPE_MMIO_STORE 5 +#define PEST_TTYPE_OTHER 7 +#define IODA3_PEST0_CA_RETURN PPC_BIT(8) +#define IODA3_PEST0_UR_RETURN PPC_BIT(9) +#define IODA3_PEST0_PCIE_NONFATAL PPC_BIT(10) +#define IODA3_PEST0_PCIE_FATAL PPC_BIT(11) +#define IODA3_PEST0_PARITY_UE PPC_BIT(13) +#define IODA3_PEST0_PCIE_CORRECTABLE PPC_BIT(14) +#define IODA3_PEST0_PCIE_INTERRUPT PPC_BIT(15) +#define IODA3_PEST0_MMIO_XLATE PPC_BIT(16) +#define IODA3_PEST0_IODA3_ERROR PPC_BIT(16) /* Same bit as MMIO xlate */ +#define IODA3_PEST0_TCE_PAGE_FAULT PPC_BIT(18) +#define IODA3_PEST0_TCE_ACCESS_FAULT PPC_BIT(19) +#define IODA3_PEST0_DMA_RESP_TIMEOUT PPC_BIT(20) +#define IODA3_PEST0_AIB_SIZE_INVALID PPC_BIT(21) +#define IODA3_PEST0_LEM_BIT PPC_BITMASK(26,31) +#define IODA3_PEST0_RID PPC_BITMASK(32,47) +#define IODA3_PEST0_MSI_DATA PPC_BITMASK(48,63) + +#define IODA3_PEST1_FAIL_ADDR PPC_BITMASK(3,63) + + +#endif /* __PHB4_REGS_H */ diff --git a/roms/skiboot/include/phb4.h b/roms/skiboot/include/phb4.h new file mode 100644 index 000000000..4f1fb31c5 --- /dev/null +++ b/roms/skiboot/include/phb4.h @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __PHB4_H +#define __PHB4_H + +#include <interrupts.h> + +/* + * Memory map + * + * In addition to the 4K MMIO registers window, the PBCQ will + * forward down one or two large MMIO regions for use by the + * PHB. + * + * We try to use the largest MMIO window for the M64 space and + * the smallest for the M32 space, but we require at least 2G + * of M32, otherwise we carve it out of M64. + */ + +#define M32_PCI_START 0x080000000 /* Offset of the actual M32 window in PCI */ +#define M32_PCI_SIZE 0x80000000ul /* Size for M32 */ + +#if 0 +/* + * Interrupt map. + * + * Each PHB supports 2K interrupt sources, which is shared by + * LSI and MSI. With default configuration, MSI would use range + * [0, 0x7f7] and LSI would use [0x7f8, 0x7ff]. The interrupt + * source should be combined with IRSN to form final hardware + * IRQ. + */ +#define PHB4_MSI_IRQ_MIN 0x000 +#define PHB4_MSI_IRQ_COUNT 0x7F8 +#define PHB4_MSI_IRQ_MAX (PHB4_MSI_IRQ_MIN+PHB4_MSI_IRQ_COUNT-1) +#define PHB4_LSI_IRQ_MIN (PHB4_MSI_IRQ_COUNT) +#define PHB4_LSI_IRQ_COUNT 8 +#define PHB4_LSI_IRQ_MAX (PHB4_LSI_IRQ_MIN+PHB4_LSI_IRQ_COUNT-1) + +#define PHB4_MSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ + PHB4_MSI_IRQ_MIN) +#define PHB4_LSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ + PHB4_LSI_IRQ_MIN) +#define PHB4_IRQ_NUM(irq) (irq & 0x7FF) + +#endif + +/* + * LSI interrupts + * + * The LSI interrupt block supports 8 interrupts. 4 of them are the + * standard PCIe INTA..INTB. The rest is for additional functions + * of the PHB + */ +#define PHB4_LSI_PCIE_INTA 0 +#define PHB4_LSI_PCIE_INTB 1 +#define PHB4_LSI_PCIE_INTC 2 +#define PHB4_LSI_PCIE_INTD 3 +#define PHB4_LSI_PCIE_INF 6 +#define PHB4_LSI_PCIE_ER 7 + +/* + * In-memory tables + * + * PHB4 requires a bunch of tables to be in memory instead of + * arrays inside the chip (unlike previous versions of the + * design). + * + * Some of them (IVT, etc...) will be provided by the OS via an + * OPAL call, not only not all of them, we also need to make sure + * some like PELT-V exist before we do our internal slot probing + * or bad thing would happen on error (the whole PHB would go into + * Fatal error state). + * + * So we maintain a set of tables internally for those mandatory + * ones within our core memory. They are fairly small. They can + * still be replaced by OS provided ones via OPAL APIs (and reset + * to the internal ones) so the OS can provide node local allocation + * for better performances. + * + * All those tables have to be naturally aligned + */ + +/* RTT Table : 128KB - Maps RID to PE# + * + * Entries are 2 bytes indexed by PCIe RID + */ +#define RTT_TABLE_ENTRIES 0x10000 +#define RTT_TABLE_SIZE 0x20000 +#define PELTV_TABLE_SIZE_MAX 0x20000 + +#define PHB4_RESERVED_PE_NUM(p) ((p)->num_pes - 1) + +/* + * PHB4 PCI slot state. When you're going to apply any + * changes here, please make sure the base state isn't + * conflicting with those defined in pci-slot.h + */ +#define PHB4_SLOT_NORMAL PCI_SLOT_STATE_NORMAL +#define PHB4_SLOT_LINK PCI_SLOT_STATE_LINK +#define PHB4_SLOT_LINK_START (PHB4_SLOT_LINK + 1) +#define PHB4_SLOT_LINK_WAIT_ELECTRICAL (PHB4_SLOT_LINK + 2) +#define PHB4_SLOT_LINK_WAIT (PHB4_SLOT_LINK + 3) +#define PHB4_SLOT_LINK_STABLE (PHB4_SLOT_LINK + 4) +#define PHB4_SLOT_HRESET PCI_SLOT_STATE_HRESET +#define PHB4_SLOT_HRESET_START (PHB4_SLOT_HRESET + 1) +#define PHB4_SLOT_HRESET_DELAY (PHB4_SLOT_HRESET + 2) +#define PHB4_SLOT_HRESET_DELAY2 (PHB4_SLOT_HRESET + 3) +#define PHB4_SLOT_FRESET PCI_SLOT_STATE_FRESET +#define PHB4_SLOT_FRESET_START (PHB4_SLOT_FRESET + 1) +#define PHB4_SLOT_FRESET_ASSERT_DELAY (PHB4_SLOT_FRESET + 2) +#define PHB4_SLOT_CRESET PCI_SLOT_STATE_CRESET +#define PHB4_SLOT_CRESET_START (PHB4_SLOT_CRESET + 1) +#define PHB4_SLOT_CRESET_WAIT_CQ (PHB4_SLOT_CRESET + 2) +#define PHB4_SLOT_CRESET_REINIT (PHB4_SLOT_CRESET + 3) +#define PHB4_SLOT_CRESET_FRESET (PHB4_SLOT_CRESET + 4) + +/* + * PHB4 error descriptor. Errors from all components (PBCQ, PHB) + * will be cached to PHB4 instance. However, PBCQ errors would + * have higher priority than those from PHB + */ +#define PHB4_ERR_SRC_NONE 0 +#define PHB4_ERR_SRC_PBCQ 1 +#define PHB4_ERR_SRC_PHB 2 + +#define PHB4_ERR_CLASS_NONE 0 +#define PHB4_ERR_CLASS_DEAD 1 +#define PHB4_ERR_CLASS_FENCED 2 +#define PHB4_ERR_CLASS_ER 3 +#define PHB4_ERR_CLASS_INF 4 +#define PHB4_ERR_CLASS_LAST 5 + +struct phb4_err { + uint32_t err_src; + uint32_t err_class; + uint32_t err_bit; +}; + +#define PHB4_LINK_LINK_RETRIES 4 +/* Link timeouts, increments of 10ms */ +#define PHB4_LINK_ELECTRICAL_RETRIES 100 +#define PHB4_LINK_WAIT_RETRIES 200 + +#define PHB4_RX_ERR_MAX 8 + +/* PHB4 flags */ +#define PHB4_AIB_FENCED 0x00000001 +#define PHB4_CFG_USE_ASB 0x00000002 +#define PHB4_CFG_BLOCKED 0x00000004 +#define PHB4_CAPP_RECOVERY 0x00000008 +#define PHB4_CAPP_DISABLE 0x00000010 +#define PHB4_ETU_IN_RESET 0x00000020 + +struct phb4 { + unsigned int index; /* 0..5 index inside p9/p10 */ + unsigned int flags; + unsigned int chip_id; /* Chip ID (== GCID on p9/p10) */ + unsigned int pec; + bool broken; + unsigned int rev; /* 00MMmmmm */ +#define PHB4_REV_NIMBUS_DD10 0xa40001 +#define PHB4_REV_NIMBUS_DD20 0xa40002 + void *regs; + void *int_mmio; + uint64_t pe_xscom; /* XSCOM bases */ + uint64_t pe_stk_xscom; + uint64_t pci_xscom; + uint64_t pci_stk_xscom; + uint64_t etu_xscom; + struct lock lock; + uint64_t mm0_base; /* Full MM window to PHB */ + uint64_t mm0_size; /* '' '' '' */ + uint64_t mm1_base; /* Full MM window to PHB */ + uint64_t mm1_size; /* '' '' '' */ + uint32_t base_msi; + uint32_t base_lsi; + uint64_t irq_port; + uint32_t num_pes; + uint32_t max_num_pes; + uint32_t num_irqs; + uint64_t creset_start_time; + + /* SkiBoot owned in-memory tables */ + __be16 *tbl_rtt; + uint8_t *tbl_peltv; + uint64_t tbl_peltv_size; + uint64_t tbl_pest; + uint64_t tbl_pest_size; + + bool skip_perst; /* Skip first perst */ + bool has_link; + int64_t ecap; /* cached PCI-E cap offset */ + int64_t aercap; /* cached AER ecap offset */ + const __be64 *lane_eq; + bool lane_eq_en; + unsigned int max_link_speed; + unsigned int dt_max_link_speed; + unsigned int max_link_width; + + uint64_t mrt_size; + uint64_t mbt_size; + uint64_t tvt_size; + + /* FIXME: dynamically allocate only what's needed below */ + uint64_t tve_cache[1024]; + uint64_t mbt_cache[32][2]; + uint64_t mdt_cache[512]; /* max num of PEs */ + uint64_t mist_cache[4096/4];/* max num of MSIs */ + uint64_t pfir_cache; /* Used by complete reset */ + uint64_t nfir_cache; /* Used by complete reset */ + bool err_pending; + struct phb4_err err; + + /* Cache some RC registers that need to be emulated */ + uint32_t rc_cache[4]; + + /* Current NPU2 relaxed ordering state */ + bool ro_state; + + /* Any capp instance attached to the PHB4 */ + struct capp *capp; + + struct phb phb; +}; + +static inline struct phb4 *phb_to_phb4(struct phb *phb) +{ + return container_of(phb, struct phb4, phb); +} + +static inline bool phb4_err_pending(struct phb4 *p) +{ + return p->err_pending; +} + +static inline void phb4_set_err_pending(struct phb4 *p, bool pending) +{ + if (!pending) { + p->err.err_src = PHB4_ERR_SRC_NONE; + p->err.err_class = PHB4_ERR_CLASS_NONE; + p->err.err_bit = -1; + } + + p->err_pending = pending; +} + +#define MAX_PHBS_PER_CHIP_P9 6 /* Max 6 PHBs per chip on p9 */ +#define MAX_PHBS_PER_CHIP_P9P 0x10 /* extra for virt PHBs */ +#define MAX_PHBS_PER_CHIP_P10 0x12 /* 6 PCI + 12 opencapi */ + +static inline int phb4_get_opal_id(unsigned int chip_id, unsigned int index) +{ + if (proc_gen == proc_gen_p10) { + return chip_id * MAX_PHBS_PER_CHIP_P10 + index; + } else { + if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P9) + return chip_id * MAX_PHBS_PER_CHIP_P9 + index; + else + return chip_id * MAX_PHBS_PER_CHIP_P9P + index; + } +} + +void phb4_pec2_dma_engine_realloc(struct phb4 *p); + +#endif /* __PHB4_H */ diff --git a/roms/skiboot/include/phys-map.h b/roms/skiboot/include/phys-map.h new file mode 100644 index 000000000..1dd337a56 --- /dev/null +++ b/roms/skiboot/include/phys-map.h @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017-2019 IBM Corp. */ + +#ifndef __PHYS_MAP_H +#define __PHYS_MAP_H + +#include <compiler.h> +#include <stdint.h> +#include <processor.h> +#include <ccan/endian/endian.h> +#include <chip.h> + +enum phys_map_type { + NULL_MAP, + SYSTEM_MEM, + GPU_MEM_4T_DOWN, + GPU_MEM_4T_UP, + OCAPI_MEM, + PHB4_64BIT_MMIO, + PHB4_32BIT_MMIO, + PHB4_XIVE_ESB, + PHB4_REG_SPC, + PHB5_64BIT_MMIO, + PHB5_32BIT_MMIO, + PHB5_XIVE_ESB, + PHB5_REG_SPC, + NPU_OCAPI_MMIO, + XIVE_VC, + XIVE_PC, + VAS_USER_WIN, + VAS_HYP_WIN, + OCAB_XIVE_ESB, + LPC_BUS, + FSP_MMIO, + NPU_REGS, + NPU_USR, + NPU_PHY, + NPU_NTL, + NPU_GENID, + PSIHB_REG, + XIVE_IC, + XIVE_TM, + PSIHB_ESB, + NX_RNG, + CENTAUR_SCOM, + MC_OCMB_CFG, + MC_OCMB_MMIO, + XSCOM, + RESV, + XIVE_NVC, + XIVE_NVPG, + XIVE_ESB, + XIVE_END, +}; + +extern void phys_map_get(uint64_t gcid, enum phys_map_type type, + int index, uint64_t *addr, uint64_t *size); + +extern void __phys_map_get(uint64_t topology_idx, uint64_t gcid, + enum phys_map_type type, int index, uint64_t *addr, uint64_t *size); + +extern void phys_map_init(unsigned long pvr); + +#endif /* __PHYS_MAP_H */ + +//TODO self test overlaps and alignemnt and size. diff --git a/roms/skiboot/include/platform.h b/roms/skiboot/include/platform.h new file mode 100644 index 000000000..d113e6eb9 --- /dev/null +++ b/roms/skiboot/include/platform.h @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __PLATFORM_H +#define __PLATFORM_H + +/* Some fwd declarations for types used further down */ +struct phb; +struct pci_device; +struct pci_slot; +struct errorlog; +struct npu2; +struct npu3; + +enum resource_id { + RESOURCE_ID_KERNEL, + RESOURCE_ID_INITRAMFS, + RESOURCE_ID_CAPP, + RESOURCE_ID_IMA_CATALOG, + RESOURCE_ID_VERSION, + RESOURCE_ID_KERNEL_FW, +}; +#define RESOURCE_SUBID_NONE 0 +#define RESOURCE_SUBID_SUPPORTED 1 + + +struct bmc_hw_config { + uint32_t scu_revision_id; + uint32_t mcr_configuration; + uint32_t mcr_scu_mpll; + uint32_t mcr_scu_strap; +}; + +struct bmc_sw_config { + /* + * Map IPMI_OEM_X to vendor commands for this BMC + * 0 = unimplimented + */ + uint32_t ipmi_oem_partial_add_esel; + uint32_t ipmi_oem_pnor_access_status; + uint32_t ipmi_oem_hiomap_cmd; +}; + +struct bmc_platform { + const char *name; + const struct bmc_hw_config *hw; + const struct bmc_sw_config *sw; +}; + +struct ocapi_phy_setup { + int tx_ffe_pre_coeff; + int tx_ffe_post_coeff; + int tx_ffe_boost_en; +}; + +/* OpenCAPI platform-specific I2C information */ +struct platform_ocapi { + uint8_t i2c_engine; /* I2C engine number */ + uint8_t i2c_port; /* I2C port number */ + uint8_t i2c_reset_addr; /* I2C address for reset */ + uint8_t i2c_reset_brick2; /* I2C pin to write to reset brick 2 */ + uint8_t i2c_reset_brick3; /* I2C pin to write to reset brick 3 */ + uint8_t i2c_reset_brick4; /* I2C pin to write to reset brick 4 */ + uint8_t i2c_reset_brick5; /* I2C pin to write to reset brick 5 */ + uint8_t i2c_presence_addr; /* I2C address for presence detection */ + uint8_t i2c_presence_brick2; /* I2C pin to read for presence on brick 2 */ + uint8_t i2c_presence_brick3; /* I2C pin to read for presence on brick 3 */ + uint8_t i2c_presence_brick4; /* I2C pin to read for presence on brick 4 */ + uint8_t i2c_presence_brick5; /* I2C pin to read for presence on brick 5 */ + bool odl_phy_swap; /* Swap ODL1 to use brick 2 rather than + * brick 1 lanes */ + const char *(*ocapi_slot_label)(uint32_t chip_id, uint32_t brick_index); + const struct ocapi_phy_setup *phy_setup; +}; + +struct dt_node; + +/* + * Just for FSP platforms, allows us to partly decouple + * FSP specific code from core code. + */ +struct platform_psi { + void (*psihb_interrupt)(void); + void (*link_established)(void); + void (*fsp_interrupt)(void); +}; + +/* + * Some PRD functionality is platform specific. + */ +struct platform_prd { + void (*msg_response)(uint32_t rc); + int (*send_error_log)(uint32_t plid, uint32_t dsize, void *data); + int (*send_hbrt_msg)(void *data, u64 dsize); + int (*wakeup)(uint32_t i_core, uint32_t i_mode); + int (*fsp_occ_load_start_status)(u64 chipid, s64 status); + int (*fsp_occ_reset_status)(u64 chipid, s64 status); +}; + +/* + * Each platform can provide a set of hooks + * that can affect the generic code + */ +struct platform { + const char *name; + + /* + * If BMC is constant, bmc platform specified here. + * Platforms can also call set_bmc_platform() if BMC platform is + * not a constant. + */ + const struct bmc_platform *bmc; + + /* + * PSI handling code. FSP specific. + */ + const struct platform_psi *psi; + + /* + * Platform specific PRD handling + */ + const struct platform_prd *prd; + + /* OpenCAPI platform-specific I2C information */ + const struct platform_ocapi *ocapi; + + /* NPU device detection */ + void (*npu2_device_detect)(struct npu2 *npu); + void (*npu3_device_detect)(struct npu3 *npu); + + /* + * Probe platform, return true on a match, called before + * any allocation has been performed outside of the heap + * so the platform can perform additional memory reservations + * here if needed. + * + * Only the boot CPU is running at this point and the cpu_thread + * structure for secondaries have not been initialized yet. The + * timebases are not synchronized. + * + * Services available: + * + * - Memory allocations / reservations + * - XSCOM + * - FSI + * - Host Services + */ + bool (*probe)(void); + + /* + * This is called right after the secondary processors are brought + * up and the timebases in sync to perform any additional platform + * specific initializations. On FSP based machines, this is where + * the FSP driver is brought up. + */ + void (*init)(void); + + /* + * Called once every thread is back in skiboot as part of fast reboot. + */ + void (*fast_reboot_init)(void); + + /* + * These are used to power down and reboot the machine + */ + int64_t (*cec_power_down)(uint64_t request); + int64_t (*cec_reboot)(void); + + /* + * This is called once per PHB before probing. It allows the + * platform to setup some PHB private data that can be used + * later on by calls such as pci_get_slot_info() below. The + * "index" argument is the PHB index within the IO HUB (or + * P8 chip). + * + * This is called before the PHB HW has been initialized. + */ + void (*pci_setup_phb)(struct phb *phb, unsigned int index); + + /* + * This is called before resetting the PHBs (lift PERST) and + * probing the devices. The PHBs have already been initialized. + */ + void (*pre_pci_fixup)(void); + /* + * Called during PCI scan for each device. For bridges, this is + * called before its children are probed. This is called for + * every device and for the PHB itself with a NULL pd though + * typically the implementation will only populate the slot + * info structure for bridge ports + */ + void (*pci_get_slot_info)(struct phb *phb, + struct pci_device *pd); + + /* + * Called for each device during pci_add_device_nodes() descend + * to create the device tree, in order to get the correct per-platform + * preference for the ibm,loc-code property + */ + void (*pci_add_loc_code)(struct dt_node *np, + struct pci_device *pd); + + /* + * Called after PCI probe is complete and before inventory is + * displayed in console. This can either run platform fixups or + * can be used to send the inventory to a service processor. + */ + void (*pci_probe_complete)(void); + + /* + * If the above is set to skiboot, the handler is here + */ + void (*external_irq)(unsigned int chip_id); + + /* + * nvram ops. + * + * Note: To keep the FSP driver simple, we only ever read the + * whole nvram once at boot and we do this passing a dst buffer + * that is 4K aligned. The read is asynchronous, the backend + * must call nvram_read_complete() when done (it's allowed to + * do it recursively from nvram_read though). + */ + int (*nvram_info)(uint32_t *total_size); + int (*nvram_start_read)(void *dst, uint32_t src, + uint32_t len); + int (*nvram_write)(uint32_t dst, void *src, uint32_t len); + + int (*secvar_init)(void); + + /* + * OCC timeout. This return how long we should wait for the OCC + * before timing out. This lets us use a high value on larger FSP + * machines and cut it off completely on BML boots and OpenPower + * machines without pre-existing OCC firmware. Returns a value in + * seconds. + */ + uint32_t (*occ_timeout)(void); + + int (*elog_commit)(struct errorlog *buf); + + /* + * Initiate loading an external resource (e.g. kernel payload, OCC) + * into a preallocated buffer. + * This is designed to asynchronously load external resources. + * Returns OPAL_SUCCESS or error. + */ + int (*start_preload_resource)(enum resource_id id, + uint32_t idx, + void *buf, size_t *len); + + /* + * Returns true when resource is loaded. + * Only has to return true once, for the + * previous start_preload_resource call for this resource. + * If not implemented, will return true and start_preload_resource + * *must* have synchronously done the load. + * Returns OPAL_SUCCESS, OPAL_BUSY or an error code + */ + int (*resource_loaded)(enum resource_id id, uint32_t idx); + + /* + * Executed just prior to creating the dtb for the kernel. + */ + void (*finalise_dt)(bool is_reboot); + + /* + * Executed just prior to handing control over to the payload. + * Used to terminate watchdogs, etc. + */ + void (*exit)(void); + + /* + * Read a sensor value + */ + int64_t (*sensor_read)(uint32_t sensor_hndl, int token, + __be64 *sensor_data); + /* + * Return the heartbeat time + */ + int (*heartbeat_time)(void); + + /* + * OPAL terminate + */ + void __attribute__((noreturn)) (*terminate)(const char *msg); + + /* + * SEEPROM update routine + */ + void (*seeprom_update)(void); + + /* + * Operator Panel display + * Physical FSP op panel or LPC port 80h + * or any other "get boot status out to the user" thing. + */ + void (*op_display)(enum op_severity sev, enum op_module mod, + uint16_t code); + + /* + * VPD load. + * Currently FSP specific. + */ + void (*vpd_iohub_load)(struct dt_node *hub_node); +}; + +extern struct platform __platforms_start; +extern struct platform __platforms_end; + +extern struct platform platform; +extern const struct bmc_platform *bmc_platform; + +extern bool manufacturing_mode; + +#define DECLARE_PLATFORM(name)\ +static const struct platform __used __section(".platforms") name ##_platform + +extern void probe_platform(void); + +extern int start_preload_resource(enum resource_id id, uint32_t subid, + void *buf, size_t *len); + +extern int resource_loaded(enum resource_id id, uint32_t idx); + +extern int wait_for_resource_loaded(enum resource_id id, uint32_t idx); + +extern void set_bmc_platform(const struct bmc_platform *bmc); + +#endif /* __PLATFORM_H */ diff --git a/roms/skiboot/include/pool.h b/roms/skiboot/include/pool.h new file mode 100644 index 000000000..967e463c5 --- /dev/null +++ b/roms/skiboot/include/pool.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2014 IBM Corp. */ + +#ifndef __POOL_H +#define __POOL_H + +#include <ccan/list/list.h> +#include <stddef.h> +#include <compiler.h> + +struct pool { + void *buf; + size_t obj_size; + struct list_head free_list; + int free_count; + int reserved; +}; + +enum pool_priority {POOL_NORMAL, POOL_HIGH}; + +void* pool_get(struct pool *pool, enum pool_priority priority) __warn_unused_result; +void pool_free_object(struct pool *pool, void *obj); +int pool_init(struct pool *pool, size_t obj_size, int count, int reserved) __warn_unused_result; + +#endif /* __POOL_H */ diff --git a/roms/skiboot/include/powercap.h b/roms/skiboot/include/powercap.h new file mode 100644 index 000000000..e47219130 --- /dev/null +++ b/roms/skiboot/include/powercap.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __POWERCAP_H +#define __POWERCAP_H + +#include <opal.h> + +enum powercap_class { + POWERCAP_CLASS_OCC, +}; + +/* + * Powercap handle is defined as u32. The first and last bytes are + * used to indicate the class and attribute. + * + * | Class | Reserved | Attribute | + * |-------|---------------|-----------| + */ + +#define powercap_make_handle(class, attr) (((class & 0xF) << 24) | (attr & 0xF)) + +#define powercap_get_class(handle) ((handle >> 24) & 0xF) +#define powercap_get_attr(handle) (handle & 0xF) + +/* Powercap OCC interface */ +int occ_get_powercap(u32 handle, u32 *pcap); +int __attribute__((__const__)) occ_set_powercap(u32 handle, int token, u32 pcap); + +#endif /* __POWERCAP_H */ diff --git a/roms/skiboot/include/prd-fw-msg.h b/roms/skiboot/include/prd-fw-msg.h new file mode 100644 index 000000000..d0e5385ff --- /dev/null +++ b/roms/skiboot/include/prd-fw-msg.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017-2019 IBM Corp. */ + +#ifndef __PRD_FW_MSG_H +#define __PRD_FW_MSG_H + +#include <types.h> + +/* Messaging structure for the opaque channel between OPAL and HBRT. This + * format is used for the firmware_request and firmware_notify interfaces + */ +enum { + PRD_FW_MSG_TYPE_REQ_NOP = 0, + PRD_FW_MSG_TYPE_RESP_NOP = 1, + PRD_FW_MSG_TYPE_RESP_GENERIC = 2, + PRD_FW_MSG_TYPE_REQ_HCODE_UPDATE = 3, + PRD_FW_MSG_TYPE_HBRT_FSP = 4, + PRD_FW_MSG_TYPE_ERROR_LOG = 5, + PRD_FW_MSG_TYPE_FSP_HBRT = 6, +}; + +struct prd_fw_msg { + __be64 type; + union { + struct { + __be64 status; + } generic_resp; + struct { + __be32 plid; + __be32 size; + char data[]; + } __packed errorlog; + struct { + char data; + } mbox_msg; + }; +}; + +#define PRD_FW_MSG_BASE_SIZE sizeof(__be64) + +#endif /* __PRD_FW_MSG_H */ diff --git a/roms/skiboot/include/processor.h b/roms/skiboot/include/processor.h new file mode 100644 index 000000000..973d7e77b --- /dev/null +++ b/roms/skiboot/include/processor.h @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __PROCESSOR_H +#define __PROCESSOR_H + +#include <bitutils.h> + +/* MSR bits */ +#define MSR_SF PPC_BIT(0) /* 64-bit mode */ +#define MSR_HV PPC_BIT(3) /* Hypervisor mode */ +#define MSR_VEC PPC_BIT(38) /* VMX enable */ +#define MSR_VSX PPC_BIT(40) /* VSX enable */ +#define MSR_S PPC_BIT(41) /* Secure mode */ +#define MSR_EE PPC_BIT(48) /* External Int. Enable */ +#define MSR_PR PPC_BIT(49) /* Problem state */ +#define MSR_FP PPC_BIT(50) /* Floating Point Enable */ +#define MSR_ME PPC_BIT(51) /* Machine Check Enable */ +#define MSR_FE0 PPC_BIT(52) /* FP Exception 0 */ +#define MSR_SE PPC_BIT(53) /* Step enable */ +#define MSR_BE PPC_BIT(54) /* Branch trace enable */ +#define MSR_FE1 PPC_BIT(55) /* FP Exception 1 */ +#define MSR_IR PPC_BIT(58) /* Instructions reloc */ +#define MSR_DR PPC_BIT(59) /* Data reloc */ +#define MSR_PMM PPC_BIT(61) /* Perf Monitor */ +#define MSR_RI PPC_BIT(62) /* Recoverable Interrupt */ +#define MSR_LE PPC_BIT(63) /* Little Endian */ + +/* PIR */ +#define SPR_PIR_P10_MASK 0x7fff /* Mask of implemented bits */ +#define SPR_PIR_P9_MASK 0x7fff /* Mask of implemented bits */ +#define SPR_PIR_P8_MASK 0x1fff /* Mask of implemented bits */ + +/* SPR register definitions */ +#define SPR_DSCR 0x011 /* RW: Data stream control reg */ +#define SPR_DSISR 0x012 /* RW: Data storage interrupt status reg */ +#define SPR_DAR 0x013 /* RW: Data address reg */ +#define SPR_DEC 0x016 /* RW: Decrement Register */ +#define SPR_SDR1 0x019 +#define SPR_SRR0 0x01a /* RW: Exception save/restore reg 0 */ +#define SPR_SRR1 0x01b /* RW: Exception save/restore reg 1 */ +#define SPR_CFAR 0x01c /* RW: Come From Address Register */ +#define SPR_AMR 0x01d /* RW: Authority Mask Register */ +#define SPR_IAMR 0x03d /* RW: Instruction Authority Mask Register */ +#define SPR_RPR 0x0ba /* RW: Relative Priority Register */ +#define SPR_TBRL 0x10c /* RO: Timebase low */ +#define SPR_TBRU 0x10d /* RO: Timebase high */ +#define SPR_SPRC 0x114 /* RW: Access to uArch SPRs (ex SCOMC) */ +#define SPR_SPRD 0x115 /* RW: Access to uArch SPRs (ex SCOMD) */ +#define SPR_SCOMC 0x114 /* RW: SCOM Control - old name of SPRC */ +#define SPR_SCOMD 0x115 /* RW: SCOM Data - old name of SPRD */ +#define SPR_TBWL 0x11c /* RW: Timebase low */ +#define SPR_TBWU 0x11d /* RW: Timebase high */ +#define SPR_TBU40 0x11e /* RW: Timebase Upper 40 bit */ +#define SPR_PVR 0x11f /* RO: Processor version register */ +#define SPR_HSPRG0 0x130 /* RW: Hypervisor scratch 0 */ +#define SPR_HSPRG1 0x131 /* RW: Hypervisor scratch 1 */ +#define SPR_SPURR 0x134 /* RW: Scaled Processor Utilization Resource */ +#define SPR_PURR 0x135 /* RW: Processor Utilization Resource reg */ +#define SPR_HDEC 0x136 /* RW: Hypervisor Decrementer */ +#define SPR_HRMOR 0x139 /* RW: Hypervisor Real Mode Offset reg */ +#define SPR_HSRR0 0x13a /* RW: HV Exception save/restore reg 0 */ +#define SPR_HSRR1 0x13b /* RW: HV Exception save/restore reg 1 */ +#define SPR_TFMR 0x13d +#define SPR_LPCR 0x13e +#define SPR_HMER 0x150 /* Hypervisor Maintenance Exception */ +#define SPR_HMEER 0x151 /* HMER interrupt enable mask */ +#define SPR_PCR 0x152 +#define SPR_AMOR 0x15d +#define SPR_USRR0 0x1fa /* RW: Ultravisor Save/Restore Register 0 */ +#define SPR_USRR1 0x1fb /* RW: Ultravisor Save/Restore Register 1 */ +#define SPR_SMFCTRL 0x1ff /* RW: Secure Memory Facility Control */ +#define SPR_PSSCR 0x357 /* RW: Stop status and control (ISA 3) */ +#define SPR_TSCR 0x399 +#define SPR_HID0 0x3f0 +#define SPR_HID1 0x3f1 +#define SPR_HID2 0x3f8 +#define SPR_HID4 0x3f4 +#define SPR_HID5 0x3f6 +#define SPR_PIR 0x3ff /* RO: Processor Identification */ + +/* Bits in SRR1 */ + +#define SPR_SRR1_PM_WAKE_MASK 0x3c0000 /* PM wake reason for P8/9 */ +#define SPR_SRR1_PM_WAKE_SRESET 0x100000 +#define SPR_SRR1_PM_WAKE_MCE 0x3c0000 /* Use reserved value for MCE */ + +/* Bits in LPCR */ + +/* Powersave Exit Cause Enable is different on each generation */ +#define SPR_LPCR_P8_PECE PPC_BITMASK(47,51) +#define SPR_LPCR_P8_PECE0 PPC_BIT(47) /* Wake on priv doorbell */ +#define SPR_LPCR_P8_PECE1 PPC_BIT(48) /* Wake on hv doorbell */ +#define SPR_LPCR_P8_PECE2 PPC_BIT(49) /* Wake on external interrupts */ +#define SPR_LPCR_P8_PECE3 PPC_BIT(50) /* Wake on decrementer */ +#define SPR_LPCR_P8_PECE4 PPC_BIT(51) /* Wake on MCs, HMIs, etc... */ + +#define SPR_LPCR_P9_PECE (PPC_BITMASK(47,51) | PPC_BITMASK(17,17)) +#define SPR_LPCR_P9_PECEU0 PPC_BIT(17) /* Wake on HVI */ +#define SPR_LPCR_P9_PECEL0 PPC_BIT(47) /* Wake on priv doorbell */ +#define SPR_LPCR_P9_PECEL1 PPC_BIT(48) /* Wake on hv doorbell */ +#define SPR_LPCR_P9_PECEL2 PPC_BIT(49) /* Wake on external interrupts */ +#define SPR_LPCR_P9_PECEL3 PPC_BIT(50) /* Wake on decrementer */ +#define SPR_LPCR_P9_PECEL4 PPC_BIT(51) /* Wake on MCs, HMIs, etc... */ +#define SPR_LPCR_P9_LD PPC_BIT(46) /* Large decrementer mode bit */ + + +/* Bits in TFMR - control bits */ +#define SPR_TFMR_MAX_CYC_BET_STEPS PPC_BITMASK(0,7) +#define SPR_TFMR_N_CLKS_PER_STEP PPC_BITMASK(8,9) +#define SPR_TFMR_MASK_HMI PPC_BIT(10) +#define SPR_TFMR_SYNC_BIT_SEL PPC_BITMASK(11,13) +#define SPR_TFMR_TB_ECLIPZ PPC_BIT(14) +#define SPR_TFMR_LOAD_TOD_MOD PPC_BIT(16) +#define SPR_TFMR_MOVE_CHIP_TOD_TO_TB PPC_BIT(18) +#define SPR_TFMR_CLEAR_TB_ERRORS PPC_BIT(24) +/* Bits in TFMR - thread indep. status bits */ +#define SPR_TFMR_TFAC_XFER_ERROR PPC_BIT(25) +#define SPR_TFMR_HDEC_PARITY_ERROR PPC_BIT(26) +#define SPR_TFMR_TBST_CORRUPT PPC_BIT(27) +#define SPR_TFMR_TBST_ENCODED PPC_BITMASK(28,31) +#define SPR_TFMR_TBST_LAST PPC_BITMASK(32,35) +#define SPR_TFMR_TB_ENABLED PPC_BIT(40) +#define SPR_TFMR_TB_VALID PPC_BIT(41) +#define SPR_TFMR_TB_SYNC_OCCURED PPC_BIT(42) +#define SPR_TFMR_TB_MISSING_SYNC PPC_BIT(43) +#define SPR_TFMR_TB_MISSING_STEP PPC_BIT(44) +#define SPR_TFMR_TB_RESIDUE_ERR PPC_BIT(45) +#define SPR_TFMR_FW_CONTROL_ERR PPC_BIT(46) +#define SPR_TFMR_CHIP_TOD_STATUS PPC_BITMASK(47,50) +#define SPR_TFMR_CHIP_TOD_INTERRUPT PPC_BIT(51) +#define SPR_TFMR_CHIP_TOD_TIMEOUT PPC_BIT(54) +#define SPR_TFMR_CHIP_TOD_PARITY_ERR PPC_BIT(56) +/* Bits in TFMR - thread specific. status bits */ +#define SPR_TFMR_PURR_PARITY_ERR PPC_BIT(57) +#define SPR_TFMR_SPURR_PARITY_ERR PPC_BIT(58) +#define SPR_TFMR_DEC_PARITY_ERR PPC_BIT(59) +#define SPR_TFMR_TFMR_CORRUPT PPC_BIT(60) +#define SPR_TFMR_PURR_OVERFLOW PPC_BIT(61) +#define SPR_TFMR_SPURR_OVERFLOW PPC_BIT(62) + +/* Bits in HMER/HMEER */ +#define SPR_HMER_MALFUNCTION_ALERT PPC_BIT(0) +#define SPR_HMER_PROC_RECV_DONE PPC_BIT(2) +#define SPR_HMER_PROC_RECV_ERROR_MASKED PPC_BIT(3) /* Not P10 */ +#define SPR_HMER_TFAC_ERROR PPC_BIT(4) +#define SPR_HMER_TFMR_PARITY_ERROR PPC_BIT(5) /* P9 */ +#define SPR_HMER_TFAC_SHADOW_XFER_ERROR PPC_BIT(5) /* P10 */ +#define SPR_HMER_SPURR_SCALE_LIMIT PPC_BIT(6) /* P10 */ +#define SPR_HMER_XSCOM_FAIL PPC_BIT(8) +#define SPR_HMER_XSCOM_DONE PPC_BIT(9) +#define SPR_HMER_PROC_RECV_AGAIN PPC_BIT(11) +#define SPR_HMER_WARN_RISE PPC_BIT(14) /* Not P10 */ +#define SPR_HMER_WARN_FALL PPC_BIT(15) /* Not P10 */ +#define SPR_HMER_SCOM_FIR_HMI PPC_BIT(16) +#define SPR_HMER_TRIG_FIR_HMI PPC_BIT(17) /* Not P10 */ +#define SPR_HMER_THD_WAKE_BLOCKED_TM_SUSPEND PPC_BIT(17) /* Not P10 */ +#define SPR_HMER_P10_TRIG_FIR_HMI PPC_BIT(18) +#define SPR_HMER_HYP_RESOURCE_ERR PPC_BIT(20) /* Not P10 */ +#define SPR_HMER_XSCOM_STATUS PPC_BITMASK(21,23) + +/* + * HMEER: initial bits for HMI interrupt enable mask. + * Per Dave Larson, never enable 8,9,21-23 + */ +#define SPR_HMEER_HMI_ENABLE_MASK (SPR_HMER_MALFUNCTION_ALERT |\ + SPR_HMER_HYP_RESOURCE_ERR |\ + SPR_HMER_PROC_RECV_DONE |\ + SPR_HMER_PROC_RECV_ERROR_MASKED |\ + SPR_HMER_TFAC_ERROR |\ + SPR_HMER_TFMR_PARITY_ERROR |\ + SPR_HMER_PROC_RECV_AGAIN) + +#define SPR_HMEER_P10_HMI_ENABLE_MASK (SPR_HMER_MALFUNCTION_ALERT |\ + SPR_HMER_PROC_RECV_DONE |\ + SPR_HMER_TFAC_ERROR |\ + SPR_HMER_TFAC_SHADOW_XFER_ERROR |\ + SPR_HMER_SPURR_SCALE_LIMIT |\ + SPR_HMER_PROC_RECV_AGAIN) + +/* Bits in HID0 */ +#define SPR_HID0_POWER8_4LPARMODE PPC_BIT(2) +#define SPR_HID0_POWER8_2LPARMODE PPC_BIT(6) +#define SPR_HID0_POWER8_DYNLPARDIS PPC_BIT(15) +#define SPR_HID0_POWER8_HILE PPC_BIT(19) +#define SPR_HID0_POWER9_HILE PPC_BIT(4) +#define SPR_HID0_POWER10_HILE PPC_BIT(4) +#define SPR_HID0_POWER8_ENABLE_ATTN PPC_BIT(31) +#define SPR_HID0_POWER9_ENABLE_ATTN (PPC_BIT(2) | PPC_BIT(3)) +#define SPR_HID0_POWER10_ENABLE_ATTN (PPC_BIT(2) | PPC_BIT(3)) +#define SPR_HID0_POWER9_RADIX PPC_BIT(8) + +/* PVR bits */ +#define SPR_PVR_TYPE 0xffff0000 +#define SPR_PVR_CHIP_TYPE 0x0000f000 +#define SPR_PVR_VERS_MAJ 0x00000f00 +#define SPR_PVR_VERS_MIN 0x000000ff + +#define PVR_TYPE(_pvr) GETFIELD(SPR_PVR_TYPE, _pvr) +#define PVR_CHIP_TYPE(_pvr) GETFIELD(SPR_PVR_CHIP_TYPE, _pvr) +#define PVR_VERS_MAJ(_pvr) GETFIELD(SPR_PVR_VERS_MAJ, _pvr) +#define PVR_VERS_MIN(_pvr) GETFIELD(SPR_PVR_VERS_MIN, _pvr) + +/* PVR definitions */ +#define PVR_TYPE_P8E 0x004b /* Murano */ +#define PVR_TYPE_P8 0x004d /* Venice */ +#define PVR_TYPE_P8NVL 0x004c /* Naples */ +#define PVR_TYPE_P9 0x004e +#define PVR_TYPE_P9P 0x004f /* Axone */ +#define PVR_TYPE_P10 0x0080 + +#ifdef __ASSEMBLY__ + +/* Thread priority control opcodes */ +#define smt_low or 1,1,1 +#define smt_medium or 2,2,2 +#define smt_high or 3,3,3 +#define smt_medium_high or 5,5,5 +#define smt_medium_low or 6,6,6 +#define smt_extra_high or 7,7,7 +#define smt_very_low or 31,31,31 +#define smt_lowest smt_low ; smt_very_low + +#else /* __ASSEMBLY__ */ + +#include <ccan/str/str.h> +#include <compiler.h> +#include <stdbool.h> +#include <stdint.h> + +#define PPC_INST_NOP 0x60000000UL +#define PPC_INST_TRAP 0x7fe00008UL + +#define RB(b) (((b) & 0x1f) << 11) +#define MSGSND(b) stringify(.long 0x7c00019c | RB(b)) +#define MSGCLR(b) stringify(.long 0x7c0001dc | RB(b)) +#define MSGSYNC stringify(.long 0x7c0006ec) + +static inline bool is_power9n(uint32_t version) +{ + if (PVR_TYPE(version) != PVR_TYPE_P9) + return false; + /* + * Bit 13 tells us: + * 0 = Scale out (aka Nimbus) + * 1 = Scale up (aka Cumulus) + */ + if ((version >> 13) & 1) + return false; + return true; +} + +static inline bool is_fused_core(uint32_t version) +{ + if (PVR_TYPE(version) == PVR_TYPE_P9) { + switch(PVR_CHIP_TYPE(version)) { + case 0: + case 2: + return true; + default: + return false; + } + + } else if(PVR_TYPE(version) == PVR_TYPE_P10) { + if(PVR_CHIP_TYPE(version) & 0x01) + return false; + else + return true; + } else + return false; +} + +static inline bool is_power9c(uint32_t version) +{ + + if (PVR_TYPE(version) != PVR_TYPE_P9) + return false; + /* + * Bit 13 tells us: + * 0 = Scale out (aka Nimbus) + * 1 = Scale up (aka Cumulus) + */ + if (!((version >> 13) & 1)) + return false; + return true; +} + +#ifndef __TEST__ + +/* POWER9 and above only */ +static inline void flush_erat(void) +{ + asm volatile("slbia 7"); +} + +/* + * SMT priority + */ + +static inline void smt_low(void) { asm volatile("or 1,1,1"); } +static inline void smt_medium(void) { asm volatile("or 2,2,2"); } +static inline void smt_high(void) { asm volatile("or 3,3,3"); } +static inline void smt_medium_high(void){ asm volatile("or 5,5,5"); } +static inline void smt_medium_low(void) { asm volatile("or 6,6,6"); } +static inline void smt_extra_high(void) { asm volatile("or 7,7,7"); } +static inline void smt_very_low(void) { asm volatile("or 31,31,31"); } +static inline void smt_lowest(void) { smt_low(); smt_very_low(); } + +/* + * SPR access functions + */ + +static inline unsigned long mfmsr(void) +{ + unsigned long val; + + asm volatile("mfmsr %0" : "=r"(val) : : "memory"); + return val; +} + +static inline void mtmsr(unsigned long val) +{ + asm volatile("mtmsr %0" : : "r"(val) : "memory"); +} + +static inline void mtmsrd(unsigned long val, int l) +{ + asm volatile("mtmsrd %0,%1" : : "r"(val), "i"(l) : "memory"); +} + +static inline __attribute__((always_inline)) +unsigned long mfspr(const unsigned int spr) +{ + unsigned long val; + + asm volatile("mfspr %0,%1" : "=r"(val) : "i"(spr) : "memory"); + return val; +} + +static inline __attribute__((always_inline)) +void mtspr(const unsigned int spr, unsigned long val) +{ + asm volatile("mtspr %0,%1" : : "i"(spr), "r"(val) : "memory"); +} + +/* Helpers for special sequences needed by some registers */ +extern void set_hid0(unsigned long hid0); +extern void trigger_attn(void); + +/* + * Barriers + */ + +static inline void eieio(void) +{ + asm volatile("eieio" : : : "memory"); +} + +static inline void sync(void) +{ + asm volatile("sync" : : : "memory"); +} + +static inline void lwsync(void) +{ + asm volatile("lwsync" : : : "memory"); +} + +static inline void isync(void) +{ + asm volatile("isync" : : : "memory"); +} + + +/* + * Cache sync + */ +static inline void sync_icache(void) +{ + asm volatile("sync; icbi 0,%0; sync; isync" : : "r" (0) : "memory"); +} + +/* + * Doorbells + */ +static inline void msgclr(void) +{ + uint64_t rb = (0x05 << (63-36)); + asm volatile(MSGCLR(%0) : : "r"(rb)); +} + +static inline void p9_dbell_receive(void) +{ + uint64_t rb = (0x05 << (63-36)); + asm volatile(MSGCLR(%0) ";" + MSGSYNC ";" + "lwsync" + : : "r"(rb)); +} + +static inline void p9_dbell_send(uint32_t pir) +{ + uint64_t rb = (0x05 << (63-36)) | pir; + asm volatile("sync ;" + MSGSND(%0) + : : "r"(rb)); +} + +/* + * Byteswap load/stores + */ + +static inline uint16_t ld_le16(const uint16_t *addr) +{ + uint16_t val; + asm volatile("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr)); + return val; +} + +static inline uint32_t ld_le32(const uint32_t *addr) +{ + uint32_t val; + asm volatile("lwbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr)); + return val; +} + +static inline void st_le16(uint16_t *addr, uint16_t val) +{ + asm volatile("sthbrx %0,0,%1" : : "r"(val), "r"(addr), "m"(*addr)); +} + +static inline void st_le32(uint32_t *addr, uint32_t val) +{ + asm volatile("stwbrx %0,0,%1" : : "r"(val), "r"(addr), "m"(*addr)); +} + +#endif /* __TEST__ */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __PROCESSOR_H */ diff --git a/roms/skiboot/include/psi.h b/roms/skiboot/include/psi.h new file mode 100644 index 000000000..ac7afa09f --- /dev/null +++ b/roms/skiboot/include/psi.h @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * IBM System P PSI (Processor Service Interface) + * + * Copyright 2013-2019 IBM Corp. + */ +#ifndef __PSI_H +#define __PSI_H + +#include <skiboot.h> + +/* + * PSI Host Bridge Registers (MMIO) + * + * The PSI interface is the bridge to the FPS, it has its own + * registers. The FSP registers appear at an offset within the + * aperture defined by the PSI_FSPBAR + */ +/* Base address of the PSI MMIO space and LSB is the enable/valid bit */ +#define PSIHB_BBAR 0x00 + +/* FSP MMIO region -- this is where the mbx regs are (offset defined below) */ +#define PSIHB_FSPBAR 0x08 + +/* FSP MMIO region mask register -- determines size of region */ +#define PSIHB_FSPMMR 0x10 + +/* TCE address register */ +#define PSIHB_TAR 0x18 +#define PSIHB_TAR_8K_ENTRIES 0 +#define PSIHB_TAR_16K_ENTRIES 1 +#define PSIHB_TAR_256K_ENTRIES 2 /* P8 only */ +#define PSIHB_TAR_512K_ENTRIES 4 /* P8 only */ + +/* PSI Host Bridge Control Register */ +#define PSIHB_CR 0x20 +#define PSIHB_CR_FSP_CMD_ENABLE PPC_BIT(0) +#define PSIHB_CR_FSP_MMIO_ENABLE PPC_BIT(1) +#define PSIHB_CR_FSP_IRQ_ENABLE PPC_BIT(3) +#define PSIHB_CR_FSP_ERR_RSP_ENABLE PPC_BIT(4) +#define PSIHB_CR_PSI_LINK_ENABLE PPC_BIT(5) +#define PSIHB_CR_FSP_RESET PPC_BIT(6) +#define PSIHB_CR_PSIHB_RESET PPC_BIT(7) +#define PSIHB10_CR_STORE_EOI PPC_BIT(12) +#define PSIHB_CR_PSI_IRQ PPC_BIT(16) /* PSIHB interrupt */ +#define PSIHB_CR_FSP_IRQ PPC_BIT(17) /* FSP interrupt */ +#define PSIHB_CR_FSP_LINK_ACTIVE PPC_BIT(18) /* FSP link active */ + +/* Error conditions in the GXHB */ +#define PSIHB_CR_PSI_ERROR PPC_BIT(32) /* PSI error */ +#define PSIHB_CR_PSI_LINK_INACTIVE PPC_BIT(33) /* Link inactive */ +#define PSIHB_CR_FSP_ACK_TIMEOUT PPC_BIT(34) /* FSP ack timeout */ +#define PSIHB_CR_MMIO_LOAD_TIMEOUT PPC_BIT(35) /* MMIO load timeout */ +#define PSIHB_CR_MMIO_LENGTH_ERROR PPC_BIT(36) /* MMIO length error */ +#define PSIHB_CR_MMIO_ADDRESS_ERROR PPC_BIT(37) /* MMIO address error */ +#define PSIHB_CR_MMIO_TYPE_ERROR PPC_BIT(38) /* MMIO type error */ +#define PSIHB_CR_UE PPC_BIT(39) /* UE detected */ +#define PSIHB_CR_PARITY_ERROR PPC_BIT(40) /* Parity error */ +#define PSIHB_CR_SYNC_ERR_ALERT1 PPC_BIT(41) /* Sync alert 1 */ +#define PSIHB_CR_SYNC_ERR_ALERT2 PPC_BIT(42) /* Sync alert 2 */ +#define PSIHB_CR_FSP_COMMAND_ERROR PPC_BIT(43) /* FSP cmd error */ + +/* PSI Status / Error Mask Register */ +#define PSIHB_SEMR 0x28 + +/* XIVR and BUID used for PSI interrupts on P8 */ +#define PSIHB_XIVR_FSP 0x30 +#define PSIHB_XIVR_OCC 0x60 +#define PSIHB_XIVR_FSI 0x68 +#define PSIHB_XIVR_LPC 0x70 +#define PSIHB_XIVR_LOCAL_ERR 0x78 +#define PSIHB_XIVR_HOST_ERR 0x80 +#define PSIHB_IRSN 0x88 +#define PSIHB_IRSN_COMP PPC_BITMASK(0,18) +#define PSIHB_IRSN_IRQ_MUX PPC_BIT(28) +#define PSIHB_IRSN_IRQ_RESET PPC_BIT(29) +#define PSIHB_IRSN_DOWNSTREAM_EN PPC_BIT(30) +#define PSIHB_IRSN_UPSTREAM_EN PPC_BIT(31) +#define PSIHB_IRSN_MASK PPC_BITMASK(32,50) + +#define PSIHB_IRQ_STATUS 0x58 +#define PSIHB_IRQ_STAT_OCC PPC_BIT(27) +#define PSIHB_IRQ_STAT_FSI PPC_BIT(28) +#define PSIHB_IRQ_STAT_LPC PPC_BIT(29) +#define PSIHB_IRQ_STAT_LOCAL_ERR PPC_BIT(30) +#define PSIHB_IRQ_STAT_HOST_ERR PPC_BIT(31) + +/* Secure version of CR for P8 and P9 (TCE enable bit) */ +#define PSIHB_PHBSCR 0x90 +#define PSIHB_PHBSCR_TCE_ENABLE PPC_BIT(2) + +/* P9 registers */ + +#define PSIHB_INTERRUPT_CONTROL 0x58 +#define PSIHB_IRQ_METHOD PPC_BIT(0) +#define PSIHB_IRQ_RESET PPC_BIT(1) +#define PSIHB_ESB_CI_BASE 0x60 +#define PSIHB10_ESB_CI_64K PPC_BIT(1) +#define PSIHB_ESB_CI_VALID PPC_BIT(63) +#define PSIHB_ESB_NOTIF_ADDR 0x68 +#define PSIHB_ESB_NOTIF_VALID PPC_BIT(63) +#define PSIHB_IVT_OFFSET 0x70 +#define PSIHB_IVT_OFF_SHIFT 32 +/* + * PSI Host Bridge Registers (XSCOM) + */ +#define PSIHB_XSCOM_P8_BASE 0xa +#define PSIHB_XSCOM_P8_HBBAR_EN PPC_BIT(63) +#define PSIHB_XSCOM_P8_HBCSR 0xe +#define PSIHB_XSCOM_P8_HBCSR_SET 0x12 +#define PSIHB_XSCOM_P8_HBCSR_CLR 0x13 +#define PSIHB_XSCOM_P8_HBSCR_FSP_IRQ PPC_BIT(17) + +#define PSIHB_XSCOM_P9_BASE 0xa +#define PSIHB_XSCOM_P9_HBBAR_EN PPC_BIT(63) +#define PSIHB_XSCOM_P9_HBCSR 0xe +#define PSIHB_XSCOM_P9_HBCSR_SET 0x12 +#define PSIHB_XSCOM_P9_HBCSR_CLR 0x13 +#define PSIHB_XSCOM_P9_HBSCR_FSP_IRQ PPC_BIT(17) + +#define PSIHB_XSCOM_P10_BASE 0xa +#define PSIHB_XSCOM_P10_HBBAR_EN PPC_BIT(63) +#define PSIHB_XSCOM_P10_HBCSR 0xe +#define PSIHB_XSCOM_P10_HBCSR_SET 0x12 +#define PSIHB_XSCOM_P10_HBCSR_CLR 0x13 +#define PSIHB_XSCOM_P10_HBSCR_FSP_IRQ PPC_BIT(17) + +/* P9 PSI Interrupts */ +#define P9_PSI_IRQ_PSI 0 +#define P9_PSI_IRQ_OCC 1 +#define P9_PSI_IRQ_FSI 2 +#define P9_PSI_IRQ_LPCHC 3 +#define P9_PSI_IRQ_LOCAL_ERR 4 +#define P9_PSI_IRQ_GLOBAL_ERR 5 +#define P9_PSI_IRQ_EXTERNAL 6 +#define P9_PSI_IRQ_LPC_SIRQ0 7 +#define P9_PSI_IRQ_LPC_SIRQ1 8 +#define P9_PSI_IRQ_LPC_SIRQ2 9 +#define P9_PSI_IRQ_LPC_SIRQ3 10 +#define P9_PSI_IRQ_SBE_I2C 11 +#define P9_PSI_IRQ_DIO 12 +#define P9_PSI_IRQ_PSU 13 +#define P9_PSI_NUM_IRQS 14 + + + +/* + * Layout of the PSI DMA address space + * + * We use a larger mapping of 256K TCEs which provides us with a 1G window in + * order to fit the trace buffers + * + * Currently we have: + * + * - 4x256K serial areas (each divided in 2: in and out buffers) + * - 1M region for inbound buffers + * - 2M region for generic data fetches + */ +#define PSI_DMA_SER0_BASE 0x00000000 +#define PSI_DMA_SER0_SIZE 0x00040000 +#define PSI_DMA_SER1_BASE 0x00040000 +#define PSI_DMA_SER1_SIZE 0x00040000 +#define PSI_DMA_SER2_BASE 0x00080000 +#define PSI_DMA_SER2_SIZE 0x00040000 +#define PSI_DMA_SER3_BASE 0x000c0000 +#define PSI_DMA_SER3_SIZE 0x00040000 +#define PSI_DMA_INBOUND_BUF 0x00100000 +#define PSI_DMA_INBOUND_SIZE 0x00100000 +#define PSI_DMA_FETCH 0x00200000 +#define PSI_DMA_FETCH_SIZE 0x00800000 +#define PSI_DMA_NVRAM_BODY 0x00a00000 +#define PSI_DMA_NVRAM_BODY_SZ 0x00100000 +#define PSI_DMA_NVRAM_TRIPL 0x00b00000 +#define PSI_DMA_NVRAM_TRIPL_SZ 0x00001000 +#define PSI_DMA_OP_PANEL_MISC 0x00b01000 +#define PSI_DMA_OP_PANEL_SIZE 0x00001000 +#define PSI_DMA_GET_SYSPARAM 0x00b02000 +#define PSI_DMA_GET_SYSPARAM_SZ 0x00001000 +#define PSI_DMA_SET_SYSPARAM 0x00b03000 +#define PSI_DMA_SET_SYSPARAM_SZ 0x00001000 +#define PSI_DMA_ERRLOG_READ_BUF 0x00b04000 +#define PSI_DMA_ERRLOG_READ_BUF_SZ 0x00040000 +#define PSI_DMA_ELOG_PANIC_WRITE_BUF 0x00b44000 +#define PSI_DMA_ELOG_PANIC_WRITE_BUF_SZ 0x00010000 +#define PSI_DMA_ERRLOG_WRITE_BUF 0x00b54000 +#define PSI_DMA_ERRLOG_WRITE_BUF_SZ 0x00040000 +#define PSI_DMA_ELOG_WR_TO_HOST_BUF 0x00b94000 /* Unused */ +#define PSI_DMA_ELOG_WR_TO_HOST_BUF_SZ 0x00010000 +#define PSI_DMA_HBRT_LOG_WRITE_BUF 0x00ba4000 +#define PSI_DMA_HBRT_LOG_WRITE_BUF_SZ 0x00001000 +#define PSI_DMA_CODE_UPD 0x00c04000 +#define PSI_DMA_CODE_UPD_SIZE 0x01001000 +#define PSI_DMA_DUMP_DATA 0x01c05000 +#define PSI_DMA_DUMP_DATA_SIZE 0x00500000 +#define PSI_DMA_SENSOR_BUF 0x02105000 +#define PSI_DMA_SENSOR_BUF_SZ 0x00080000 +#define PSI_DMA_MDST_TABLE 0x02185000 +#define PSI_DMA_MDST_TABLE_SIZE 0x00001000 +#define PSI_DMA_HYP_DUMP 0x02186000 +#define PSI_DMA_HYP_DUMP_SIZE 0x01000000 +#define PSI_DMA_PCIE_INVENTORY 0x03186000 +#define PSI_DMA_PCIE_INVENTORY_SIZE 0x00010000 +#define PSI_DMA_LED_BUF 0x03196000 +#define PSI_DMA_LED_BUF_SZ 0x00001000 +#define PSI_DMA_LOC_COD_BUF 0x03197000 +#define PSI_DMA_LOC_COD_BUF_SZ 0x00008000 +#define PSI_DMA_MEMCONS 0x0319f000 +#define PSI_DMA_MEMCONS_SZ 0x00001000 +#define PSI_DMA_LOG_BUF 0x03200000 +#define PSI_DMA_LOG_BUF_SZ 0x00100000 /* INMEM_CON_LEN */ +#define PSI_DMA_PLAT_REQ_BUF 0x03300000 +#define PSI_DMA_PLAT_REQ_BUF_SIZE 0x00001000 +#define PSI_DMA_PLAT_RESP_BUF 0x03301000 +#define PSI_DMA_PLAT_RESP_BUF_SIZE 0x00001000 +/* + * Our PRD interface can handle upto 64KB data transfer between + * OPAL - opal-prd. Hence adding TCE size as 68KB. If we increase + * OPAL - opal-prd message size, then we have to fix this. + */ +#define PSI_DMA_HBRT_FSP_MSG 0x03302000 +#define PSI_DMA_HBRT_FSP_MSG_SIZE 0x00011000 + +#define PSI_DMA_TRACE_BASE 0x04000000 + +struct psi { + struct list_node list; + uint64_t xscom_base; + void *regs; + void *esb_mmio; + unsigned int chip_id; + unsigned int interrupt; + bool active; + bool no_lpc_irqs; + struct dt_node *node; +}; + +extern void psi_set_link_polling(bool active); + +extern struct psi *first_psi; +extern void psi_init(void); +extern struct psi *psi_find_link(uint32_t chip_id); +extern void psi_init_for_fsp(struct psi *psi); +extern void psi_disable_link(struct psi *psi); +extern void psi_reset_fsp(struct psi *psi); +extern bool psi_check_link_active(struct psi *psi); +extern bool psi_poll_fsp_interrupt(struct psi *psi); +extern struct psi *psi_find_functional_chip(void); + +/* Interrupts */ +extern void psi_irq_reset(void); +extern void psi_enable_fsp_interrupt(struct psi *psi); +extern void psi_fsp_link_in_use(struct psi *psi); + +extern struct lock psi_lock; + +#endif /* __PSI_H */ diff --git a/roms/skiboot/include/psr.h b/roms/skiboot/include/psr.h new file mode 100644 index 000000000..c057a99f9 --- /dev/null +++ b/roms/skiboot/include/psr.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __PSR_H +#define __PSR_H + +#include <opal.h> + +enum psr_class { + PSR_CLASS_OCC, +}; + +/* + * PSR handle is defined as u32. The first and last bytes are + * used to indicate the class and type. RID indiactes psr class + * specific data. For PSR_CLASS_OCC psr class RID is the chip index. + * + * | Class |Reserved| RID | Type | + * |-------|--------|------|------| + */ + +#define psr_make_handle(class, rid, type) (((class & 0xF) << 24) | \ + ((rid & 0xF) << 8) | (type & 0xF)) + +#define psr_get_class(handle) ((handle >> 24) & 0xF) +#define psr_get_rid(handle) ((handle >> 8) & 0xF) +#define psr_get_type(handle) (handle & 0xF) + +/* Powercap OCC interface */ +int occ_get_psr(u32 handle, u32 *ratio); +int occ_set_psr(u32 handle, int token, u32 ratio); + +#endif /* __PSR_H */ diff --git a/roms/skiboot/include/ras.h b/roms/skiboot/include/ras.h new file mode 100644 index 000000000..d0faaeefb --- /dev/null +++ b/roms/skiboot/include/ras.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2020 IBM Corp. */ + +#ifndef __RAS_H +#define __RAS_H + +#include <compiler.h> +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <bitutils.h> +#include <types.h> + +#include <ccan/container_of/container_of.h> +#include <ccan/list/list.h> +#include <ccan/short_types/short_types.h> +#include <ccan/build_assert/build_assert.h> +#include <ccan/array_size/array_size.h> +#include <ccan/endian/endian.h> +#include <ccan/str/str.h> + +#include <processor.h> + +#define MCE_NO_ERROR 0x0001 +#define MCE_UNKNOWN 0x0002 +#define MCE_INSNFETCH 0x0004 +#define MCE_LOADSTORE 0x0008 +#define MCE_TABLE_WALK 0x0010 +#define MCE_IMPRECISE 0x0020 +#define MCE_MEMORY_ERROR 0x0040 +#define MCE_SLB_ERROR 0x0080 +#define MCE_ERAT_ERROR 0x0100 +#define MCE_TLB_ERROR 0x0200 +#define MCE_TLBIE_ERROR 0x0400 +#define MCE_INVOLVED_EA 0x0800 +#define MCE_INVOLVED_PA 0x1000 + +void decode_mce(uint64_t srr0, uint64_t srr1, + uint32_t dsisr, uint64_t dar, + uint64_t *type, const char **error_str, + uint64_t *address); + +#endif /* __RAS_H */ diff --git a/roms/skiboot/include/rtc.h b/roms/skiboot/include/rtc.h new file mode 100644 index 000000000..b6658248e --- /dev/null +++ b/roms/skiboot/include/rtc.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2014 IBM Corp. */ + +#ifndef __RTC_H +#define __RTC_H + +#include <time-utils.h> + +/* + * Update the cache to the current time as specified by tm. + */ +void rtc_cache_update(struct tm *tm); + +/* + * Get the current time based on the cache. If the cache is valid the result + * is returned in tm and the function returns 0. Otherwise returns -1. + */ +int rtc_cache_get(struct tm *tm); + +/* + * Same as the previous function except the result is returned as an OPAL + * datetime. + */ +int rtc_cache_get_datetime(uint32_t *year_month_day, + uint64_t *hour_minute_second_millisecond); + +#endif diff --git a/roms/skiboot/include/sbe-p8.h b/roms/skiboot/include/sbe-p8.h new file mode 100644 index 000000000..66f702514 --- /dev/null +++ b/roms/skiboot/include/sbe-p8.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __SBE_P8_H +#define __SBE_P8_H + +/* P8 SBE update timer function */ +extern void p8_sbe_update_timer_expiry(uint64_t new_target); + +/* Is SBE timer available ? */ +extern bool p8_sbe_timer_ok(void); + +/* Initialize SBE timer */ +extern void p8_sbe_init_timer(void); + +#endif /* __SBE_P8_H */ diff --git a/roms/skiboot/include/sbe-p9.h b/roms/skiboot/include/sbe-p9.h new file mode 100644 index 000000000..289c28ba5 --- /dev/null +++ b/roms/skiboot/include/sbe-p9.h @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017-2019 IBM Corp. */ + +#ifndef __SBE_P9_H +#define __SBE_P9_H + +#include <bitutils.h> +#include <ccan/list/list.h> +#include <ccan/short_types/short_types.h> + +/* Worst case command timeout value (90 sec) */ +#define SBE_CMD_TIMEOUT_MAX (90 * 1000) + +/* Primary response status code */ +#define SBE_STATUS_PRI_SUCCESS 0x00 +#define SBE_STATUS_PRI_INVALID_CMD 0x01 +#define SBE_STATUS_PRI_INVALID_DATA 0x02 +#define SBE_STATUS_PRI_SEQ_ERR 0x03 +#define SBE_STATUS_PRI_INTERNAL_ERR 0x04 +#define SBE_STATUS_PRI_UNSECURE_ACCESS 0x05 +#define SBE_STATUS_PRI_GENERIC_ERR 0xFE + +/* Secondary response status code */ +#define SBE_STATUS_SEC_SUCCESS 0x00 +#define SBE_STATUS_SEC_CMD_CLASS_UNSUPPORTED 0x01 +#define SBE_STATUS_SEC_CMD_UNSUPPORTED 0x02 +#define SBE_STATUS_SEC_INV_ADDR 0x03 +#define SBE_STATUS_SEC_INV_TARGET_TYPE 0x04 +#define SBE_STATUS_SEC_INV_CHIPLET_ID 0x05 +#define SBE_STATUS_SEC_TARGET_NOT_PRESENT 0x06 +#define SBE_STATUS_SEC_TARGET_NOT_FUNC 0x07 +#define SBE_STATUS_SEC_CMD_NOT_ALLOW 0x08 +#define SBE_STATUS_SEC_FUNC_NOT_SUPPORTED 0x09 +#define SBE_STATUS_SEC_GENERIC_ERR 0x0A +#define SBE_STATUS_SEC_BLACKLIST_REG 0x0B +#define SBE_STATUS_SEC_OS_FAILURE 0x0C +#define SBE_STATUS_SEC_MBX_REG_FAILURE 0x0D +#define SBE_STATUS_SEC_INSUFFICIENT_DATA 0x0E +#define SBE_STATUS_SEC_EXCESS_DATA 0x0F +#define SBE_STATUS_SEC_HW_TIMEOUT 0x10 +#define SBE_STATUS_SEC_PCBPIB_ERR 0x11 +#define SBE_STATUS_SEC_FIFO_PARITY_ERR 0x12 +#define SBE_STATUS_SEC_TIMER_EXPIRED 0x13 +#define SBE_STATUS_SEC_BLACKLISTED_MEM 0x14 +#define SBE_STATUS_SEC_UNSEC_REGION_NOT_FOUND 0x15 +#define SBE_STATUS_SEC_UNSEC_REGION_EXCEEDED 0x16 +#define SBE_STATUS_SEC_UNSEC_REGION_AMEND 0x17 +#define SBE_STATUS_SEC_INPUT_BUF_OVERFLOW 0x18 +#define SBE_STATUS_SEC_INVALID_PARAMS 0x19 +#define SBE_STATUS_SEC_BLACKLISTED_CMD 0x20 + +/* Number of MBOX register on each side */ +#define NR_HOST_SBE_MBOX_REG 0x04 + +/* + * SBE MBOX register address + * Reg 0 - 3 : Host to send command packets to SBE + * Reg 4 - 7 : SBE to send response packets to Host + */ +#define PSU_HOST_SBE_MBOX_REG0 0x000D0050 +#define PSU_HOST_SBE_MBOX_REG1 0x000D0051 +#define PSU_HOST_SBE_MBOX_REG2 0x000D0052 +#define PSU_HOST_SBE_MBOX_REG3 0x000D0053 +#define PSU_HOST_SBE_MBOX_REG4 0x000D0054 +#define PSU_HOST_SBE_MBOX_REG5 0x000D0055 +#define PSU_HOST_SBE_MBOX_REG6 0x000D0056 +#define PSU_HOST_SBE_MBOX_REG7 0x000D0057 +#define PSU_SBE_DOORBELL_REG_RW 0x000D0060 +#define PSU_SBE_DOORBELL_REG_AND 0x000D0061 +#define PSU_SBE_DOORBELL_REG_OR 0x000D0062 +#define PSU_HOST_DOORBELL_REG_RW 0x000D0063 +#define PSU_HOST_DOORBELL_REG_AND 0x000D0064 +#define PSU_HOST_DOORBELL_REG_OR 0x000D0065 + +/* + * Doorbell register to trigger SBE interrupt. Set by OPAL to inform + * the SBE about a waiting message in the Host/SBE mailbox registers + */ +#define HOST_SBE_MSG_WAITING PPC_BIT(0) + +/* + * Doorbell register for host bridge interrupt. Set by the SBE to inform + * host about a response message in the Host/SBE mailbox registers + */ +#define SBE_HOST_RESPONSE_WAITING PPC_BIT(0) +#define SBE_HOST_MSG_READ PPC_BIT(1) +#define SBE_HOST_STOP15_EXIT PPC_BIT(2) +#define SBE_HOST_RESET PPC_BIT(3) +#define SBE_HOST_PASSTHROUGH PPC_BIT(4) +#define SBE_HOST_TIMER_EXPIRY PPC_BIT(14) +#define SBE_HOST_RESPONSE_MASK (PPC_BITMASK(0, 4) | SBE_HOST_TIMER_EXPIRY) + +/* SBE Control Register */ +#define SBE_CONTROL_REG_RW 0x00050008 + +/* SBE interrupt s0/s1 bits */ +#define SBE_CONTROL_REG_S0 PPC_BIT(14) +#define SBE_CONTROL_REG_S1 PPC_BIT(15) + +/* SBE Target Type */ +#define SBE_TARGET_TYPE_PROC 0x00 +#define SBE_TARGET_TYPE_EX 0x01 +#define SBE_TARGET_TYPE_PERV 0x02 +#define SBE_TARGET_TYPE_MCS 0x03 +#define SBE_TARGET_TYPE_EQ 0x04 +#define SBE_TARGET_TYPE_CORE 0x05 + +/* SBE MBOX command class */ +#define SBE_MCLASS_FIRST 0xD1 +#define SBE_MCLASS_CORE_STATE 0xD1 +#define SBE_MCLASS_SCOM 0xD2 +#define SBE_MCLASS_RING 0xD3 +#define SBE_MCLASS_TIMER 0xD4 +#define SBE_MCLASS_MPIPL 0xD5 +#define SBE_MCLASS_SECURITY 0xD6 +#define SBE_MCLASS_GENERIC 0xD7 +#define SBE_MCLASS_LAST 0xD7 + +/* + * Commands are provided in xxyy form where: + * - xx : command class + * - yy : command + * + * Both request and response message uses same seq ID, + * command class and command. + */ +#define SBE_CMD_CTRL_DEADMAN_LOOP 0xD101 +#define SBE_CMD_MULTI_SCOM 0xD201 +#define SBE_CMD_PUT_RING_FORM_IMAGE 0xD301 +#define SBE_CMD_CONTROL_TIMER 0xD401 +#define SBE_CMD_GET_ARCHITECTED_REG 0xD501 +#define SBE_CMD_CLR_ARCHITECTED_REG 0xD502 +#define SBE_CMD_SET_UNSEC_MEM_WINDOW 0xD601 +#define SBE_CMD_GET_SBE_FFDC 0xD701 +#define SBE_CMD_GET_CAPABILITY 0xD702 +#define SBE_CMD_READ_SBE_SEEPROM 0xD703 +#define SBE_CMD_SET_FFDC_ADDR 0xD704 +#define SBE_CMD_QUIESCE_SBE 0xD705 +#define SBE_CMD_SET_FABRIC_ID_MAP 0xD706 +#define SBE_CMD_STASH_MPIPL_CONFIG 0xD707 + +/* SBE MBOX control flags */ + +/* Generic flags */ +#define SBE_CMD_CTRL_RESP_REQ 0x0100 +#define SBE_CMD_CTRL_ACK_REQ 0x0200 + +/* Deadman loop */ +#define CTRL_DEADMAN_LOOP_START 0x0001 +#define CTRL_DEADMAN_LOOP_STOP 0x0002 + +/* Control timer */ +#define CONTROL_TIMER_START 0x0001 +#define CONTROL_TIMER_STOP 0x0002 + +/* Stash MPIPL config */ +#define SBE_STASH_KEY_SKIBOOT_BASE 0x03 + +/* SBE message state */ +enum p9_sbe_msg_state { + sbe_msg_unused = 0, /* Free */ + sbe_msg_queued, /* Queued to SBE list */ + sbe_msg_sent, /* Sent to SBE */ + sbe_msg_wresp, /* Waiting for response */ + sbe_msg_done, /* Complete */ + sbe_msg_timeout, /* Message timeout */ + sbe_msg_error, /* Failed to send message to SBE */ +}; + +/* SBE message */ +struct p9_sbe_msg { + /* + * Reg[0] : + * word0 : + * direct cmd : reserved << 16 | ctrl flag + * indirect cmd: mem_addr_size_dword + * response : primary status << 16 | secondary status + * + * word1 : seq id << 16 | cmd class << 8 | cmd + * + * WARNING: + * - Don't populate reg[0].seq (byte 4,5). This will be populated by + * p9_sbe_queue_msg(). + */ + u64 reg[4]; + + /* cmd timout : mftb() + msecs_to_tb(SBE_CMD_TIMEOUT_MAX) */ + u64 timeout; + + /* Completion function */ + void (*complete)(struct p9_sbe_msg *msg); + void *user_data; + + /* Current msg state */ + enum p9_sbe_msg_state state; + + /* Set if the message expects a response */ + bool response; + + /* Response will be filled by driver when response received */ + struct p9_sbe_msg *resp; + + /* Internal queuing */ + struct list_node link; +}; + + +/* Allocate and populate p9_sbe_msg structure */ +extern struct p9_sbe_msg *p9_sbe_mkmsg(u16 cmd, u16 ctrl_flag, u64 reg1, + u64 reg2, u64 reg3) __warn_unused_result; + +/* Free p9_sbe_msg structure */ +extern void p9_sbe_freemsg(struct p9_sbe_msg *msg); + +/* Add new message to sbe queue */ +extern int p9_sbe_queue_msg(uint32_t chip_id, struct p9_sbe_msg *msg, + void (*comp)(struct p9_sbe_msg *msg)) __warn_unused_result; + +/* Synchronously send message to SBE */ +extern int p9_sbe_sync_msg(u32 chip_id, struct p9_sbe_msg *msg, bool autofree); + +/* Remove message from SBE queue, it will not remove inflight message */ +extern int p9_sbe_cancelmsg(u32 chip_id, struct p9_sbe_msg *msg); + +/* Initialize the SBE mailbox driver */ +extern void p9_sbe_init(void); + +/* SBE interrupt */ +extern void p9_sbe_interrupt(uint32_t chip_id); + +/* Is SBE timer available ? */ +extern bool p9_sbe_timer_ok(void); + +/* Update SBE timer expiry */ +extern void p9_sbe_update_timer_expiry(uint64_t new_target); + +/* Send skiboot relocated base address to SBE */ +extern void p9_sbe_send_relocated_base(uint64_t reloc_base); + +/* Terminate and trigger MPIPL */ +extern void p9_sbe_terminate(void); + +#endif /* __SBE_P9_H */ diff --git a/roms/skiboot/include/secvar.h b/roms/skiboot/include/secvar.h new file mode 100644 index 000000000..413d7997e --- /dev/null +++ b/roms/skiboot/include/secvar.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2019 IBM Corp. */ + +#ifndef _SECVAR_DRIVER_ +#define _SECVAR_DRIVER_ + +#include <stdint.h> + +struct secvar; + +struct secvar_storage_driver { + int (*load_bank)(struct list_head *bank, int section); + int (*write_bank)(struct list_head *bank, int section); + int (*store_init)(void); + void (*lockdown)(void); + uint64_t max_var_size; +}; + +struct secvar_backend_driver { + /* Perform any pre-processing stuff (e.g. determine secure boot state) */ + int (*pre_process)(struct list_head *variable_bank, + struct list_head *update_bank); + + /* Process all updates */ + int (*process)(struct list_head *variable_bank, + struct list_head *update_bank); + + /* Perform any post-processing stuff (e.g. derive/update variables)*/ + int (*post_process)(struct list_head *variable_bank, + struct list_head *update_bank); + + /* Validate a single variable, return boolean */ + int (*validate)(struct secvar *var); + + /* String to use for compatible in secvar node */ + const char *compatible; +}; + +extern struct secvar_storage_driver secboot_tpm_driver; +extern struct secvar_backend_driver edk2_compatible_v1; + +int secvar_main(struct secvar_storage_driver, struct secvar_backend_driver); + +#endif diff --git a/roms/skiboot/include/sensor.h b/roms/skiboot/include/sensor.h new file mode 100644 index 000000000..905bd501d --- /dev/null +++ b/roms/skiboot/include/sensor.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2017 IBM Corp. */ + +#ifndef __SENSOR_H +#define __SENSOR_H + +/* + * A sensor handler is a four bytes value which identifies a sensor by + * its resource class (temperature, fans ...), a resource identifier + * and an attribute number (data, status, ...) : + * + * Res. + * | Attr. |Fam Class| Resource Id | + * |--------|---|-----|----------------| + * + * The last 3bits of the resource class are used to hold the family + * number. That leaves 32 differents resource classes. This is enough + * for the FSP as it uses 15. + */ + +/* + * Helper routines to build or use the sensor handler. + */ +#define sensor_make_handler(family, class, rid, attr) \ + (((attr) << 24) | ((family) & 0x7) << 21 | ((class) & 0x1f) << 16 | \ + ((rid) & 0xffff)) + +#define sensor_get_family(handler) (((handler) >> 21) & 0x7) +#define sensor_get_frc(handler) (((handler) >> 16) & 0x1f) +#define sensor_get_rid(handler) ((handler) & 0xffff) +#define sensor_get_attr(handler) ((handler) >> 24) + +/* + * Sensor families + * + * This identifier is used to dispatch calls to OPAL_SENSOR_READ to + * the appropriate component. FSP is the initial family and you can + * have up to eight, as we are hijacking the last 3bits of the + * resource class. + */ +enum { + SENSOR_FSP = 0, + SENSOR_OCC = 6, + SENSOR_DTS = 7, +}; + +/* + * root node of all sensors : /ibm,opal/sensors + */ +extern struct dt_node *sensor_node; + +extern void sensor_init(void); +extern void check_sensor_read(int token); + +#endif /* __SENSOR_H */ diff --git a/roms/skiboot/include/sfc-ctrl.h b/roms/skiboot/include/sfc-ctrl.h new file mode 100644 index 000000000..d3889bbd0 --- /dev/null +++ b/roms/skiboot/include/sfc-ctrl.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2014 IBM Corp. */ + +#ifndef SFC_CTRL_H +#define SFC_CTRL_H + +struct spi_flash_ctrl; + +extern int sfc_open(struct spi_flash_ctrl **ctrl); +extern void sfc_close(struct spi_flash_ctrl *ctrl); + +#endif /* SFC_CTRL_H */ diff --git a/roms/skiboot/include/skiboot-valgrind.h b/roms/skiboot/include/skiboot-valgrind.h new file mode 100644 index 000000000..c9cd7cb35 --- /dev/null +++ b/roms/skiboot/include/skiboot-valgrind.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2017 IBM Corp. */ + +#ifndef __SKIBOOT_VALGRIND_H +#define __SKIBOOT_VALGRIND_H + +#ifdef USE_VALGRIND +#include <valgrind/valgrind.h> +#include <valgrind/memcheck.h> +#else + +#define RUNNING_ON_VALGRIND 0 + +#define VALGRIND_MAKE_MEM_UNDEFINED(p, len) \ + do { \ + (void)(p); \ + (void)(len); \ + } while (0) + +#endif + +#endif /* __SKIBOOT_VALGRIND_H */ diff --git a/roms/skiboot/include/skiboot.h b/roms/skiboot/include/skiboot.h new file mode 100644 index 000000000..f3378ec28 --- /dev/null +++ b/roms/skiboot/include/skiboot.h @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __SKIBOOT_H +#define __SKIBOOT_H + +#include <compiler.h> +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <bitutils.h> +#include <types.h> + +#include <ccan/container_of/container_of.h> +#include <ccan/list/list.h> +#include <ccan/short_types/short_types.h> +#include <ccan/build_assert/build_assert.h> +#include <ccan/array_size/array_size.h> +#include <ccan/endian/endian.h> +#include <ccan/str/str.h> + +#include <libflash/blocklevel.h> + +#include <mem-map.h> +#include <op-panel.h> +#include <platform.h> + +/* Special ELF sections */ +#define __force_data __section(".force.data") + +struct mem_region; +extern struct mem_region *mem_region_next(struct mem_region *region); + +/* Misc linker script symbols */ +extern char _start[]; +extern char _head_end[]; +extern char _stext[]; +extern char _etext[]; +extern char __sym_map_end[]; +extern char _romem_end[]; + +#ifndef __TESTING__ +/* Readonly section start and end. */ +extern char __rodata_start[], __rodata_end[]; + +static inline bool is_rodata(const void *p) +{ + return ((const char *)p >= __rodata_start && (const char *)p < __rodata_end); +} +#else +static inline bool is_rodata(const void *p) +{ + return false; +} +#endif + +/* Console logging + * Update console_get_level() if you add here + */ +#define PR_EMERG 0 +#define PR_ALERT 1 +#define PR_CRIT 2 +#define PR_ERR 3 +#define PR_WARNING 4 +#define PR_NOTICE 5 +#define PR_PRINTF PR_NOTICE +#define PR_INFO 6 +#define PR_DEBUG 7 +#define PR_TRACE 8 +#define PR_INSANE 9 + +#ifndef pr_fmt +#define pr_fmt(fmt) fmt +#endif + +void _prlog(int log_level, const char* fmt, ...) __attribute__((format (printf, 2, 3))); +#define prlog(l, f, ...) do { _prlog(l, pr_fmt(f), ##__VA_ARGS__); } while(0) +#define prerror(fmt...) do { prlog(PR_ERR, fmt); } while(0) +#define prlog_once(arg, ...) \ +({ \ + static bool __prlog_once = false; \ + if (!__prlog_once) { \ + __prlog_once = true; \ + prlog(arg, ##__VA_ARGS__); \ + } \ +}) + +/* Location codes -- at most 80 chars with null termination */ +#define LOC_CODE_SIZE 80 + +/* Processor generation */ +enum proc_gen { + proc_gen_unknown, + proc_gen_p8, + proc_gen_p9, + proc_gen_p10, +}; +extern enum proc_gen proc_gen; + +extern unsigned int pcie_max_link_speed; + +/* Convert a 4-bit number to a hex char */ +extern char __attrconst tohex(uint8_t nibble); + +#ifndef __TEST__ +/* Bit position of the most significant 1-bit (LSB=0, MSB=63) */ +static inline int ilog2(unsigned long val) +{ + int left_zeros; + + asm volatile ("cntlzd %0,%1" : "=r" (left_zeros) : "r" (val)); + + return 63 - left_zeros; +} + +static inline bool is_pow2(unsigned long val) +{ + return val == (1ul << ilog2(val)); +} +#endif + +#define lo32(x) ((x) & 0xffffffff) +#define hi32(x) (((x) >> 32) & 0xffffffff) + +/* WARNING: _a *MUST* be a power of two */ +#define ALIGN_UP(_v, _a) (((_v) + (_a) - 1) & ~((_a) - 1)) +#define ALIGN_DOWN(_v, _a) ((_v) & ~((_a) - 1)) + +/* TCE alignment */ +#define TCE_SHIFT 12 +#define TCE_PSIZE (1ul << 12) +#define TCE_MASK (TCE_PSIZE - 1) + +/* Not the greatest variants but will do for now ... */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +/* PCI Geographical Addressing */ +#define PCI_BUS_NUM(bdfn) (((bdfn) >> 8) & 0xff) +#define PCI_DEV(bdfn) (((bdfn) >> 3) & 0x1f) +#define PCI_FUNC(bdfn) ((bdfn) & 0x07) + +/* + * To help the FSP to distinguish between physical address and TCE mapped address. + * Also to help hostboot to distinguish physical and relative address. + */ +#define HRMOR_BIT (1ul << 63) + +/* Clean the stray high bit which the FSP inserts: we only have 52 bits real */ +static inline u64 cleanup_addr(u64 addr) +{ + return addr & ((1ULL << 52) - 1); +} + +/* Start the kernel */ +extern void start_kernel(uint64_t entry, void* fdt, + uint64_t mem_top) __noreturn; +extern void start_kernel32(uint64_t entry, void* fdt, + uint64_t mem_top) __noreturn; +extern void start_kernel_secondary(uint64_t entry) __noreturn; + +/* Get description of machine from HDAT and create device-tree */ +extern int parse_hdat(bool is_opal); + +struct dt_node; + +/* Add /cpus/features node for boot environment that passes an fdt */ +extern void dt_add_cpufeatures(struct dt_node *root); + +/* Root of device tree. */ +extern struct dt_node *dt_root; + +/* Full skiboot version number (possibly includes gitid). */ +extern const char version[]; + +/* Debug support */ +extern char __sym_map_start[]; +extern char __sym_map_end[]; +extern size_t snprintf_symbol(char *buf, size_t len, uint64_t addr); + +/* Direct controls */ +extern void direct_controls_init(void); +extern int64_t opal_signal_system_reset(int cpu_nr); + +/* Fast reboot support */ +extern void disable_fast_reboot(const char *reason); +extern void add_fast_reboot_dt_entries(void); +extern void fast_reboot(void); +extern void __noreturn __secondary_cpu_entry(void); +extern void __noreturn load_and_boot_kernel(bool is_reboot); +extern void cleanup_local_tlb(void); +extern void cleanup_global_tlb(void); +extern void init_shared_sprs(void); +extern void init_replicated_sprs(void); +extern bool start_preload_kernel(void); +extern void copy_exception_vectors(void); +extern void copy_sreset_vector(void); +extern void copy_sreset_vector_fast_reboot(void); +extern void patch_traps(bool enable); + +/* Various probe routines, to replace with an initcall system */ +extern void probe_phb3(void); +extern void probe_phb4(void); +extern int preload_capp_ucode(void); +extern void preload_io_vpd(void); +extern void probe_npu(void); +extern void probe_npu2(void); +extern void probe_npu3(void); +extern void uart_init(void); +extern void mbox_init(void); +extern void early_uart_init(void); +extern void homer_init(void); +extern void slw_init(void); +extern void add_cpu_idle_state_properties(void); +extern void lpc_rtc_init(void); + +/* flash support */ +struct flash_chip; +extern int flash_register(struct blocklevel_device *bl); +extern int flash_start_preload_resource(enum resource_id id, uint32_t subid, + void *buf, size_t *len); +extern int flash_resource_loaded(enum resource_id id, uint32_t idx); +extern bool flash_reserve(void); +extern void flash_release(void); +extern bool flash_unregister(void); +#define FLASH_SUBPART_ALIGNMENT 0x1000 +#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT +extern int flash_subpart_info(void *part_header, uint32_t header_len, + uint32_t part_size, uint32_t *part_actual, + uint32_t subid, uint32_t *offset, + uint32_t *size); +extern void flash_fw_version_preload(void); +extern void flash_dt_add_fw_version(void); +extern const char *flash_map_resource_name(enum resource_id id); +extern int flash_secboot_info(uint32_t *total_size); +extern int flash_secboot_read(void *dst, uint32_t src, uint32_t len); +extern int flash_secboot_write(uint32_t dst, void *src, uint32_t len); + +/* + * Decompression routines + * + * The below structure members are needed for the xz library routines, + * src: Source address (The compressed binary) + * src_size: Source size + * dst: Destination address (The memory area where the `src` will be + * decompressed) + * dst_size: Destination size + */ +struct xz_decompress { + void *dst; + void *src; + size_t dst_size; + size_t src_size; + /* The status of the decompress process: + - OPAL_PARTIAL: if the job is in progress + - OPAL_SUCCESS: if the job is successful + - OPAL_NO_MEM: memory allocation failure + - OPAL_PARAMETER: If any of the above (src, dst..) are invalid or + if xz decompress fails. In which case the caller should check the + xz_error for failure reason. + */ + int status; + int xz_error; + /* The decompression job, this will be freed if the caller uses + * `wait_xz_decompression` function, in any other case its the + * responsibility of caller to free the allocation job. */ + struct cpu_job *job; +}; + +extern void xz_start_decompress(struct xz_decompress *); +extern void wait_xz_decompress(struct xz_decompress *); + +/* NVRAM support */ +extern void nvram_init(void); +extern void nvram_read_complete(bool success); + +/* UART stuff */ +enum { + UART_CONSOLE_OPAL, + UART_CONSOLE_OS +}; +extern void uart_set_console_policy(int policy); +extern bool uart_enabled(void); + +/* PRD */ +extern void prd_psi_interrupt(uint32_t proc); +extern void prd_tmgt_interrupt(uint32_t proc); +extern void prd_occ_reset(uint32_t proc); +extern void prd_sbe_passthrough(uint32_t proc); +extern void prd_init(void); +extern void prd_register_reserved_memory(void); +extern void prd_fsp_occ_reset(uint32_t proc); +extern void prd_fsp_occ_load_start(u32 proc); +extern void prd_fw_resp_fsp_response(int status); +extern int prd_hbrt_fsp_msg_notify(void *data, u32 dsize); + +/* Flatten device-tree */ +extern void *create_dtb(const struct dt_node *root, bool exclusive); + +/* Track failure in Wakup engine */ +enum wakeup_engine_states { + WAKEUP_ENGINE_NOT_PRESENT, + WAKEUP_ENGINE_PRESENT, + WAKEUP_ENGINE_FAILED +}; +extern enum wakeup_engine_states wakeup_engine_state; +extern bool has_deep_states; +extern void nx_p9_rng_late_init(void); + + + +/* SLW reinit function for switching core settings */ +extern int64_t slw_reinit(uint64_t flags); + +/* Patch SPR in SLW image */ +extern int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val); + +extern void fast_sleep_exit(void); + +/* Fallback fake RTC */ +extern void fake_rtc_init(void); + +/* Exceptions */ +struct stack_frame; +extern void exception_entry(struct stack_frame *stack); +extern void exception_entry_pm_sreset(void); +extern void __noreturn exception_entry_pm_mce(void); + +/* Assembly in head.S */ +extern void disable_machine_check(void); +extern void enable_machine_check(void); +extern unsigned int enter_p8_pm_state(bool winkle); +extern unsigned int enter_p9_pm_state(uint64_t psscr); +extern void enter_p9_pm_lite_state(uint64_t psscr); +extern uint32_t reset_patch_start; +extern uint32_t reset_patch_end; +extern uint32_t reset_fast_reboot_patch_start; +extern uint32_t reset_fast_reboot_patch_end; + +/* Fallback fake NVRAM */ +extern int fake_nvram_info(uint32_t *total_size); +extern int fake_nvram_start_read(void *dst, uint32_t src, uint32_t len); +extern int fake_nvram_write(uint32_t offset, void *src, uint32_t size); + +#endif /* __SKIBOOT_H */ diff --git a/roms/skiboot/include/spcn.h b/roms/skiboot/include/spcn.h new file mode 100644 index 000000000..d0ee2d5ac --- /dev/null +++ b/roms/skiboot/include/spcn.h @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2016 IBM Corp. */ + +#ifndef __SPCN_H +#define __SPCN_H + + +/* SPCN commands */ +#define SPCN_CMD_PRS 0x42 /* Power Resource Status */ +#define SPCN_CMD_SET 0x66 /* Set Environmental Thresholds */ + +/* SPCN command address modes */ +#define SPCN_ADDR_MODE_CEC_NODE 0x0000d000 /* CEC node single destination */ +#define SPCN_ADDR_MODE_ALL_SLAVES 0x0000f000 /* Address all slaves in all racks */ +#define SPCN_ADDR_MODE_RACK_NODES 0x00000000 /* Address rack node in all racks */ + +/* SPCN PRS command modifiers */ +#define SPCN_MOD_PRS_STATUS_FIRST 0x01 /* Power Resource Status (First 1KB) */ +#define SPCN_MOD_PRS_STATUS_SUBS 0x02 /* Subsequent set of 1KB PRS entries */ +#define SPCN_MOD_PRS_LED_DATA_FIRST 0x51 /* LED data entry (First 1KB) */ +#define SPCN_MOD_PRS_LED_DATA_SUB 0x52 /* Subsequent LED data entries */ + +/* SPCN SET command modifiers */ +#define SPCN_MOD_SET_LED_CTL_LOC_CODE 0x07 /* Control LED with location code */ +#define SPCN_MOD_SET_IDENTIFY_OFF_ENC 0x08 /* Turn off identify LEDs in CEC */ +#define SPCN_MOD_SET_IDENTIFY_OFF_NODE 0x0B /* Turn off identify LEDs in Node */ + +/* SPCN SENSOR command modifiers */ +#define SPCN_MOD_SENSOR_PARAM_FIRST 0x10 /* First 1K sensor parameters */ +#define SPCN_MOD_SENSOR_PARAM_SUBS 0x11 /* Subsequent sensor parameters */ +#define SPCN_MOD_SENSOR_DATA_FIRST 0x12 /* First 1K sensor data */ +#define SPCN_MOD_SENSOR_DATA_SUBS 0x13 /* Subsequent sensor data blocks */ +#define SPCN_MOD_PROC_JUNC_TEMP 0x14 /* Process junction temperatures */ +#define SPCN_MOD_SENSOR_POWER 0x1c /* System power consumption */ +#define SPCN_MOD_LAST 0xff + +/* + * Modifiers 0x53 and 0x54 are used by LEDS at standby. So HV does not come into + * the picture here. Do we need those? + */ + +/* Supported SPCN response codes */ +#define LOGICAL_IND_STATE_MASK 0x10 /* If set, control fault state */ +#define ACTIVE_LED_STATE_MASK 0x01 /* If set, switch on the LED */ +#define SPCN_LED_IDENTIFY_MASK 0x80 /* Set identify indicator */ +#define SPCN_LED_FAULT_MASK 0x40 /* Set fault indicator */ +#define SPCN_LED_TRANS_MASK 0x20 /* LED is in transition */ +#define SPCN_CLR_LED_STATE 0x00 /* Reset identify indicator */ + +/* SPCN command response status codes */ +enum spcn_rsp_status { + SPCN_RSP_STATUS_SUCCESS = 0x01, /* Command successful */ + SPCN_RSP_STATUS_COND_SUCCESS = 0x02, /* Command successful, but additional entries exist */ + SPCN_RSP_STATUS_INVALID_RACK = 0x15, /* Invalid rack command */ + SPCN_RSP_STATUS_INVALID_SLAVE = 0x16, /* Invalid slave command */ + SPCN_RSP_STATUS_INVALID_MOD = 0x18, /* Invalid modifier */ + SPCN_RSP_STATUS_STATE_PROHIBIT = 0x21, /* Present state prohibits */ + SPCN_RSP_STATUS_UNKNOWN = 0xff, /* Default state */ +}; + +/* Sensor FRCs (Frame resource class) */ +enum { + SENSOR_FRC_POWER_CTRL = 0x02, + SENSOR_FRC_POWER_SUPPLY, + SENSOR_FRC_REGULATOR, + SENSOR_FRC_COOLING_FAN, + SENSOR_FRC_COOLING_CTRL, + SENSOR_FRC_BATTERY_CHRG, + SENSOR_FRC_BATTERY_PACK, + SENSOR_FRC_AMB_TEMP, + SENSOR_FRC_TEMP, + SENSOR_FRC_VRM, + SENSOR_FRC_RISER_CARD, + SENSOR_FRC_IO_BP, +}; + +/* + * Common to all PRS modifiers (subcommands) + */ +struct sensor_header { + __be16 frc; /* Frame resource class */ + __be16 rid; /* Resource ID */ +} __packed; + +/* + * Data layout for PRS modifier PRS_STATUS 0x01, 0x02 + */ +struct sensor_prs { + struct sensor_header header; + __be16 src; /* unused */ + __be16 status; +} __packed; + +#define PRS_STATUS_ON_SUPPORTED 0x0010 +#define PRS_STATUS_ON 0x0008 +#define PRS_STATUS_AC_FAULTED 0x0004 +#define PRS_STATUS_FAULTED 0x0002 +#define PRS_STATUS_PRESENT 0x0001 + +/* + * Data layout for PRS modifier SENSOR_PARAM 0x10, 0x11 + */ +struct sensor_param { + struct sensor_header header; + char location[4]; + char __reserved[4]; + __be16 threshold; + __be16 status; +} __packed; + +/* + * Data layout for PRS modifier SENSOR_DATA 0x12, 0x13 + */ +struct sensor_data { + struct sensor_header header; + __be16 data; + __be16 status; +} __packed; + +#define SENSOR_STATUS_EM_ALERT 0x0004 +#define SENSOR_STATUS_FAULTED 0x0002 +#define SENSOR_STATUS_PRESENT 0x0001 + +/* Power sensor is retrieved through a new PRS modifier 0x1C, data + * response is as follows: + * + * Byte 0: + * + * Bit 7: Data valid + * Bit 4-6: reserved + * Bit 0-3: Number of power supply or data records + * + * Each data record is 5 Bytes following above byte 0: + * + * Data Record: Byte 0: Power supply ID {00, 01, 02, 03, ...} + * Byte 1-4: Power sensor value in milli-watts + * + * Example Power Sensor data: (Tuleta) + * 84 00 00 00 00 00 + * 01 00 00 00 00 + * 02 00 02 5d 78 + * 03 00 02 0f 58 + * 00 00 00 00 00 + * + * 0x84: Bit 7 is valid bit and there are 4 power supplies + * 0x00 00 00 00 00 + * | ^^^^^^^^^^^ Power in milli-watts + * \-- Power supply ID + * + * Ox03 00 02 0f 58 + * | ^^^^^^^^^^^ Power in milli-watts (135000 mW) + * \-- Power supply ID + */ + +#define POWER_SUPPLY_MAX 8 + +struct sensor_power_supply { + uint8_t rid; /* Power supply ID */ + __be32 milliwatts; +} __packed; + +struct sensor_power { + uint8_t status; + struct sensor_power_supply supplies[POWER_SUPPLY_MAX]; +} __packed; + +#define sensor_power_is_valid(s) ((s)->status & 0x80) +#define sensor_power_count(s) ((s)->status & 0x0f) + + +#endif /* __SPCN_H */ diff --git a/roms/skiboot/include/stack.h b/roms/skiboot/include/stack.h new file mode 100644 index 000000000..3e987ea81 --- /dev/null +++ b/roms/skiboot/include/stack.h @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __STACKFRAME_H +#define __STACKFRAME_H + +#include <mem-map.h> + +#define STACK_ENTRY_OPAL_API 0 /* OPAL call */ +#define STACK_ENTRY_HMI 0x0e60 /* Hypervisor maintenance */ +#define STACK_ENTRY_RESET 0x0100 /* System reset */ +#define STACK_ENTRY_SOFTPATCH 0x1500 /* Soft patch (denorm emulation) */ + +#if HAVE_BIG_ENDIAN +#define STACK_TOC_OFFSET 40 +#else +#define STACK_TOC_OFFSET 24 +#endif + +/* Safety/ABI gap at top of stack */ +#define STACK_TOP_GAP 0x100 + +/* Remaining stack space (gap included) */ +#define NORMAL_STACK_SIZE (STACK_SIZE/2) + +/* Emergency (re-entry) stack size */ +#define EMERGENCY_STACK_SIZE (STACK_SIZE/2) + +/* Offset to get to normal CPU stacks */ +#define CPU_STACKS_OFFSET (CPU_STACKS_BASE + \ + NORMAL_STACK_SIZE - STACK_TOP_GAP) + +/* Offset to get to emergency CPU stacks */ +#define EMERGENCY_CPU_STACKS_OFFSET (CPU_STACKS_BASE + NORMAL_STACK_SIZE + \ + EMERGENCY_STACK_SIZE - STACK_TOP_GAP) + +/* Gap below the stack. If our stack checker sees the stack below that + * gap, it will flag a stack overflow + */ +#define STACK_SAFETY_GAP 512 + +/* Warning threshold, if stack goes below that on mcount, print a + * warning. + */ +#define STACK_WARNING_GAP 2048 + +#define STACK_CHECK_GUARD_BASE 0xdeadf00dbaad300 +#define STACK_INT_MAGIC 0xb1ab1af00ba1234ULL + +#ifndef __ASSEMBLY__ + +#include <stdint.h> +#include <opal-api.h> + +/* This is the struct used to save GPRs etc.. on OPAL entry + * and from some exceptions. It is not always entirely populated + * depending on the entry type + */ +struct stack_frame { + /* Standard 112-byte stack frame header (the minimum size required, + * using an 8-doubleword param save area). The callee (in C) may use + * lrsave; we declare these here so we don't get our own save area + * overwritten */ + uint64_t backchain; + uint64_t crsave; + uint64_t lrsave; + uint64_t compiler_dw; + uint64_t linker_dw; + uint64_t tocsave; + uint64_t paramsave[8]; + + /* Space for stack-local vars used by asm. At present we only use + * one doubleword. */ + uint64_t locals[1]; + + /* Interrupt entry magic value */ + uint64_t magic; + + /* Entry type */ + uint64_t type; + + /* GPR save area + * + * We don't necessarily save everything in here + */ + uint64_t gpr[32]; + + /* Other SPR saved + * + * Only for some exceptions. + */ + uint32_t cr; + uint32_t xer; + uint32_t dsisr; + uint64_t ctr; + uint64_t lr; + uint64_t pc; + uint64_t msr; + uint64_t cfar; + uint64_t srr0; + uint64_t srr1; + uint64_t hsrr0; + uint64_t hsrr1; + uint64_t dar; +} __attribute__((aligned(16))); + +/* Backtrace entry */ +struct bt_entry { + unsigned long sp; + unsigned long pc; + unsigned long exception_type; + unsigned long exception_pc; +}; + +/* Backtrace metadata */ +struct bt_metadata { + unsigned int ents; + unsigned long token; + unsigned long r1_caller; + unsigned long pir; +}; + +/* Boot stack top */ +extern void *boot_stack_top; + +/* Create a backtrace */ +void backtrace_create(struct bt_entry *entries, unsigned int max_ents, + struct bt_metadata *metadata); + +/* Convert a backtrace to ASCII */ +extern void backtrace_print(struct bt_entry *entries, + struct bt_metadata *metadata, char *out_buf, + unsigned int *len, bool symbols); + +/* For use by debug code, create and print backtrace, uses a static buffer */ +extern void backtrace(void); + +/* For use by exception debug code, supply an r1 */ +extern void backtrace_r1(uint64_t r1); + +#ifdef STACK_CHECK_ENABLED +extern void check_stacks(void); +#else +static inline void check_stacks(void) { } +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __STACKFRAME_H */ + diff --git a/roms/skiboot/include/time-utils.h b/roms/skiboot/include/time-utils.h new file mode 100644 index 000000000..0e9f837d4 --- /dev/null +++ b/roms/skiboot/include/time-utils.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __TIME_UTILS_H +#define __TIME_UTILS_H + +#include <stdint.h> +#include <time.h> + +/* BCD conversion utilities. MSB is byte 3, LSB is byte 0 */ + +static inline unsigned int bcd_byte(uint32_t bcd, int byteno) +{ + bcd >>= byteno * 8; + return (bcd >> 4 & 0xf) * 10 + (bcd & 0xf); +} + +static inline uint32_t int_to_bcd2(unsigned int x) +{ + return (((x / 10) << 4) & 0xf0) | (x % 10); +} + +static inline uint32_t int_to_bcd4(unsigned int x) +{ + return int_to_bcd2(x / 100) << 8 | int_to_bcd2(x % 100); +} + +void tm_to_datetime(struct tm *tm, uint32_t *y_m_d, uint64_t *h_m_s_m); +void datetime_to_tm(uint32_t y_m_d, uint64_t h_m_s_m, struct tm *tm); + +#endif diff --git a/roms/skiboot/include/timebase.h b/roms/skiboot/include/timebase.h new file mode 100644 index 000000000..07967e2b2 --- /dev/null +++ b/roms/skiboot/include/timebase.h @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Timebase helpers. + * + * Note: Only use after the TODs are in sync ! + * + * Copyright 2013-2016 IBM Corp. + */ + +#ifndef __TIME_H +#define __TIME_H + +#include <time.h> + +#ifndef __TEST__ +static inline unsigned long mftb(void) +{ + unsigned long tb; + + /* We use a memory clobber to avoid this being + * moved in the instruction stream + */ + asm volatile("mftb %0" : "=r"(tb) : : "memory"); + return tb; +} +#endif + +enum tb_cmpval { + TB_ABEFOREB = -1, + TB_AEQUALB = 0, + TB_AAFTERB = 1 +}; + +static inline enum tb_cmpval tb_compare(unsigned long a, + unsigned long b) +{ + if (a == b) + return TB_AEQUALB; + return ((long)(b - a)) > 0 ? TB_ABEFOREB : TB_AAFTERB; +} + +/* Architected timebase */ +extern unsigned long tb_hz; + +static inline unsigned long secs_to_tb(unsigned long secs) +{ + return secs * tb_hz; +} + +static inline unsigned long tb_to_secs(unsigned long tb) +{ + return tb / tb_hz; +} + +static inline unsigned long tb_remaining_nsecs(unsigned long tb) +{ + return tb % tb_hz; +} + +static inline unsigned long msecs_to_tb(unsigned long msecs) +{ + return msecs * (tb_hz / 1000); +} + +static inline unsigned long tb_to_msecs(unsigned long tb) +{ + return (tb * 1000) / tb_hz; +} + +static inline unsigned long usecs_to_tb(unsigned long usecs) +{ + return usecs * (tb_hz / 1000000); +} + +static inline unsigned long tb_to_usecs(unsigned long tb) +{ + return (tb * 1000000) / tb_hz; +} + +extern unsigned long timespec_to_tb(const struct timespec *ts); + +/* time_wait - Wait a certain number of TB ticks while polling FSP */ +extern void time_wait(unsigned long duration); +extern void time_wait_nopoll(unsigned long duration); + +/* time_wait_ms - Wait a certain number of milliseconds while polling FSP */ +extern void time_wait_ms(unsigned long ms); +extern void time_wait_ms_nopoll(unsigned long ms); + +/* time_wait_us - Wait a certain number of microseconds while polling FSP */ +extern void time_wait_us(unsigned long us); +extern void time_wait_us_nopoll(unsigned long us); + +/* nanosleep_nopoll - variant for use from hostservices */ +extern int nanosleep_nopoll(const struct timespec *req, struct timespec *rem); +#endif /* __TIME_H */ diff --git a/roms/skiboot/include/timer.h b/roms/skiboot/include/timer.h new file mode 100644 index 000000000..d19053277 --- /dev/null +++ b/roms/skiboot/include/timer.h @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2014-2015 IBM Corp. */ + +#ifndef __TIMER_H +#define __TIMER_H + +#include <stdint.h> +#include <ccan/list/list.h> + +struct timer; + +typedef void (*timer_func_t)(struct timer *t, void *data, uint64_t now); + +/* Structure exposed in order to be able to allocate it + * statically but otherwise, use accessors, don't access + * the fields directly + * + * WARNING: Do not free a timer object unless you have cancelled + * it first or you know it won't reschedule itself and have done + * a sync_timer() on it. The timer core *will* access the object + * again after you return from the expiry callback so it must not + * be freed from the callback itself. + */ +struct timer { + struct list_node link; + uint64_t target; + timer_func_t expiry; + void * user_data; + void * running; + uint64_t gen; +}; + +extern void init_timer(struct timer *t, timer_func_t expiry, void *data); + +/* (re)schedule a timer. If already scheduled, it's expiry will be updated + * + * This doesn't synchronize so if the timer also reschedules itself there + * is no telling which one "wins". The advantage is that this can be called + * with any lock held or from the timer expiry itself. + * + * We support a magic expiry of TIMER_POLL which causes a given timer to + * be called whenever OPAL main polling loop is run, which is often during + * boot and occasionally while Linux is up. This can be used with both + * schedule_timer() and schedule_timer_at() + * + * This is useful for a number of interrupt driven drivers to have a way + * to crank their state machine at times when the interrupt isn't available + * such as during early boot. + * + * Note: For convenience, schedule_timer() returns the current TB value + */ +#define TIMER_POLL ((uint64_t)-1) +extern uint64_t schedule_timer(struct timer *t, uint64_t how_long); +extern void schedule_timer_at(struct timer *t, uint64_t when); + +/* Synchronization point with the timer. If the callback has started before + * that function is called, it will be complete when this function returns. + * + * It might start *again* but at least anything before this will be visible + * to any subsequent occurrence. + * + * The usual issue of such sync functions exist: don't call it while holding + * a lock that the timer callback might take or from the timer expiry itself. + */ +extern void sync_timer(struct timer *t); + +/* cancel_timer() will ensure the timer isn't concurrently running so + * the cancellation is guaranteed even if the timer reschedules itself. + * + * This uses sync_timer() internally so don't call this while holding a + * lock the timer might use. + */ +extern void cancel_timer(struct timer *t); + +/* cancel_timer_async() allows to remove the timer from the schedule + * list without trying to synchronize. This is useful if the cancellation + * must happen while holding locks that would make the synchronization + * impossible. The user is responsible of ensuring it deals with potentially + * spurrious occurrences + */ +extern void cancel_timer_async(struct timer *t); + +/* Run the timers */ +extern void check_timers(bool from_interrupt); + +/* Core init */ +void late_init_timers(void); + +#endif /* __TIMER_H */ diff --git a/roms/skiboot/include/trace.h b/roms/skiboot/include/trace.h new file mode 100644 index 000000000..1b1be249c --- /dev/null +++ b/roms/skiboot/include/trace.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __TRACE_H +#define __TRACE_H +#include <ccan/short_types/short_types.h> +#include <stddef.h> +#include <lock.h> +#include <trace_types.h> + + +struct cpu_thread; + +/* Here's one we prepared earlier. */ +void init_boot_tracebuf(struct cpu_thread *boot_cpu); + +struct trace_info { + /* Lock for writers. Exposed to kernel. */ + struct lock lock; + /* Exposed to kernel. */ + struct tracebuf tb; +}; + +#define TBUF_SZ ((1024 * 1024) - sizeof(struct trace_info) - sizeof(union trace)) + +/* Allocate trace buffers once we know memory topology */ +void init_trace_buffers(void); +void trace_add_dt_props(void); + +/* This will fill in timestamp and cpu; you must do type and len. */ +void trace_add(union trace *trace, u8 type, u16 len); + +/* Put trace node into dt. */ +void trace_add_node(void); +#endif /* __TRACE_H */ diff --git a/roms/skiboot/include/trace_types.h b/roms/skiboot/include/trace_types.h new file mode 100644 index 000000000..4ebf5a0a8 --- /dev/null +++ b/roms/skiboot/include/trace_types.h @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * API for kernel to read trace buffer. + * + * Copyright 2013-2019 IBM Corp. + */ + +#ifndef __TRACE_TYPES_H +#define __TRACE_TYPES_H + +#include <types.h> + +#define TRACE_REPEAT 1 +#define TRACE_OVERFLOW 2 +#define TRACE_OPAL 3 /* OPAL call */ +#define TRACE_FSP_MSG 4 /* FSP message sent/received */ +#define TRACE_FSP_EVENT 5 /* FSP driver event */ +#define TRACE_UART 6 /* UART driver traces */ +#define TRACE_I2C 7 /* I2C driver traces */ + +/* One per cpu, plus one for NMIs */ +struct tracebuf { + /* Size used to get buffer offset */ + __be64 buf_size; + /* This where the buffer starts. */ + __be64 start; + /* This is where writer has written to. */ + __be64 end; + /* This is where the writer wrote to previously. */ + __be64 last; + /* Maximum possible size of a record. */ + __be32 max_size; + + char buf[/* TBUF_SZ + max_size */]; +}; + +/* Common header for all trace entries. */ +struct trace_hdr { + __be64 timestamp; + u8 type; + u8 len_div_8; + __be16 cpu; + u8 unused[4]; +}; + +/* Note: all other entries must be at least as large as this! */ +struct trace_repeat { + __be64 timestamp; /* Last repeat happened at this timestamp */ + u8 type; /* == TRACE_REPEAT */ + u8 len_div_8; + __be16 cpu; + __be16 prev_len; + __be16 num; /* Starts at 1, ie. 1 repeat, or two traces. */ + /* Note that the count can be one short, if read races a repeat. */ +}; + +/* Overflow is special */ +struct trace_overflow { + __be64 unused64; /* Timestamp is unused */ + u8 type; /* == TRACE_OVERFLOW */ + u8 len_div_8; + u8 unused[6]; /* ie. hdr.cpu is indeterminate */ + __be64 bytes_missed; +}; + +/* All other trace types have a full header */ +struct trace_opal { + struct trace_hdr hdr; + __be64 token, lr, sp, r3_to_11[9]; +}; + +#define TRACE_FSP_MSG_IN 0 +#define TRACE_FSP_MSG_OUT 1 + +struct trace_fsp_msg { + struct trace_hdr hdr; + __be32 word0; + __be32 word1; + u8 dlen; + u8 dir; /* TRACE_FSP_MSG_IN or TRACE_FSP_MSG_OUT */ + u8 data[56]; /* See dlen, but max is 56 bytes. */ +}; + +#define TRACE_FSP_EVT_LINK_DOWN 0 +#define TRACE_FSP_EVT_DISR_CHG 1 /* 0:disr */ +#define TRACE_FSP_EVT_SOFT_RR 2 /* 0:disr */ +#define TRACE_FSP_EVT_RR_COMPL 3 +#define TRACE_FSP_EVT_HDES_CHG 4 /* 0:hdes */ +#define TRACE_FSP_EVT_POLL_IRQ 5 /* 0:irq? 1:hdir 2:ctl 3:psi_irq */ + +struct trace_fsp_event { + struct trace_hdr hdr; + __be16 event; + __be16 fsp_state; + __be32 data[4]; /* event type specific */ +}; + +#define TRACE_UART_CTX_IRQ 0 +#define TRACE_UART_CTX_POLL 1 +#define TRACE_UART_CTX_READ 2 + +struct trace_uart { + struct trace_hdr hdr; + u8 ctx; + u8 cnt; + u8 irq_state; + u8 unused; + __be16 in_count; +}; + +struct trace_i2c { + struct trace_hdr hdr; + u16 bus; + u16 type; + u16 i2c_addr; + u16 smbus_reg; + u16 size; + s16 rc; +}; + +union trace { + struct trace_hdr hdr; + /* Trace types go here... */ + struct trace_repeat repeat; + struct trace_overflow overflow; + struct trace_opal opal; + struct trace_fsp_msg fsp_msg; + struct trace_fsp_event fsp_evt; + struct trace_uart uart; + struct trace_i2c i2c; +}; + +#endif /* __TRACE_TYPES_H */ diff --git a/roms/skiboot/include/types.h b/roms/skiboot/include/types.h new file mode 100644 index 000000000..498ee66c2 --- /dev/null +++ b/roms/skiboot/include/types.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2015 IBM Corp. */ + +#ifndef __TYPES_H +#define __TYPES_H +#include <ccan/short_types/short_types.h> +#include <ccan/endian/endian.h> + +/* These are currently just for clarity, but we could apply sparse. */ +typedef beint16_t __be16; +typedef beint32_t __be32; +typedef beint64_t __be64; + +typedef leint16_t __le16; +typedef leint32_t __le32; +typedef leint64_t __le64; + +#endif /* __TYPES_H */ + diff --git a/roms/skiboot/include/vas.h b/roms/skiboot/include/vas.h new file mode 100644 index 000000000..1f59b1d9c --- /dev/null +++ b/roms/skiboot/include/vas.h @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2018 IBM Corp. */ + +#ifndef __VAS_H +#define __VAS_H + +#include <xscom.h> + +/* + * Abbreviations used in VAS: + * WC: Window Context + * WCM: Window Context MMIO + * HVWC: Hypervisor Window Context + * UWC: OS/User Window Context + * UWCM: OS/User Window Context MMIO + * WIDM: Window ID MMIO + * BAR: Base Address Register + * BAMR: Base Address Mask Register + * N (S): North (South) + * CONTS Contents + * FIR: Fault Isolation Register + * RMA: Real Mode Addressing + * CQ: (Power Bus) Common Queue + */ + +extern void vas_init(void); +extern __attrconst bool vas_nx_enabled(void); +extern __attrconst uint64_t vas_get_hvwc_mmio_bar(const int chipid); +extern __attrconst uint64_t vas_get_wcbs_bar(int chipid); +extern __attrconst uint64_t vas_get_rma_bar(int chipid); + +/* + * HVWC and UWC BAR. + * + * A Power node can have (upto?) 8 Power chips. + * + * There is one instance of VAS in each Power chip. Each instance of VAS + * has 64K windows, which can be used to send/receive messages from + * software threads and coprocessors. + * + * Each window is described by two types of window contexts: + * + * Hypervisor Window Context (HVWC) of size VAS_HVWC_SIZE bytes + * OS/User Window Context (UWC) of size VAS_UWC_SIZE bytes. + * + * A window context can be viewed as a set of 64-bit registers. The settings + * of these registers control/determine the behavior of the VAS hardware + * when messages are sent/received through the window. + * + * Each Power chip i.e each instance of VAS, is assigned two distinct ranges + * (one for each type of context) of Power-bus addresses (aka Base Address + * Region or BAR) which can be used to access the window contexts in that + * instance of VAS. + * + * The HVWC BAR for a chip is the contigous region of power-bus addresses + * containing the (64K) hypervisor window contexts of the chip. Similarly, + * the UWC BAR is the region of power-bus addresses containing the 64K + * OS/User Window contexts of the chip. We get the start address of the + * HVWC and UWC BAR using phys_map_get(). See also get_hvwc_mmio_bar() + * and get_uwc_mmio_bar(). + */ +/* Window Context Backing Store Size */ +#define VAS_WCBS_SIZE 0x800000 /* 8MB */ + +/* Window context size of each window */ +#define VAS_WC_SIZE 512 + +#define VAS_WINDOWS_PER_CHIP 65536 /* 64K */ + +/* + * SCOM Base Address from P9/P10 SCOM Assignment spreadsheet + */ +#define P9_VAS_SCOM_BASE_ADDR 0x03011800 +#define VAS_SCOM_BASE_ADDR 0x02011400 + +/* + * NOTE: VAS_SCOM_BASE_ADDR (0x3011800) includes the SCOM ring of 6. So, + * setting the ring to 0 here. + * + * The satellite and offset values below are from "Table 3.1 VAS + * Internal Register Listing" of the P9 VAS Workbook. + */ +#define VAS_P9_SAT(sat, offset) XSCOM_SAT(0x0, sat, offset) + +#define VAS_FIR0 VAS_P9_SAT(0x0, 0x0) +#define VAS_FIR_MASK VAS_P9_SAT(0x0, 0x3) +#define VAS_FIR_ACTION0 VAS_P9_SAT(0x0, 0x6) +#define VAS_FIR_ACTION1 VAS_P9_SAT(0x0, 0x7) + +#define VAS_WCM_BAR VAS_P9_SAT(0x0, 0xA) +#define VAS_UWCM_BAR VAS_P9_SAT(0x0, 0xB) +#define VAS_BUF_CTL VAS_P9_SAT(0x0, 0xC) +#define VAS_MISC_N_CTL VAS_P9_SAT(0x0, 0xD) +#define VAS_RMA_BAR VAS_P9_SAT(0x0, 0xE) +#define VAS_RMA_BAMR VAS_P9_SAT(0x0, 0xF) +#define VAS_WIDM_CTL VAS_P9_SAT(0x0, 0x29) +#define VAS_WIDM_DATA VAS_P9_SAT(0x0, 0x2A) +#define VAS_IN_CERR_RPT_CONTS VAS_P9_SAT(0x0, 0x2B) +#define VAS_RG_CERR_RPT_CONTS VAS_P9_SAT(0x0, 0x2C) +#define VAS_WIDM_ECC VAS_P9_SAT(0x0, 0x31) + +#define VAS_WCBS_BAR VAS_P9_SAT(0x1, 0x0) +#define VAS_CQ_CERR_RPT_CONTS VAS_P9_SAT(0x1, 0x8) +#define VAS_WC_CERR_RPT_CONTS VAS_P9_SAT(0x1, 0x9) +#define VAS_EG_CERR_RPT_CONTS VAS_P9_SAT(0x1, 0xA) + +#define VAS_PB_CFG0 VAS_P9_SAT(0x1, 0xD) +#define VAS_PB_CFG1 VAS_P9_SAT(0x1, 0xE) +#define VAS_MISC_S_CTL VAS_P9_SAT(0x1, 0xF) + +#define VAS_BUF_CTL_FREE_COUNT PPC_BITMASK(49:55) +#define VAS_BUF_CTL_USED_COUNT PPC_BITMASK(57:63) +#define VAS_RMA_BAR_ADDR PPC_BITMASK(8, 51) +#define VAS_RMA_BAMR_MASK PPC_BITMASK(8, 51) + +/* Some VAS Miscellaneous Status and North Control Register bits. */ +#define VAS_64K_MODE_MASK PPC_BIT(0) +#define VAS_ACCEPT_PASTE_MASK PPC_BIT(1) +#define VAS_QUIESCE_REQ_MASK PPC_BIT(4) +#define VAS_ENABLE_WC_MMIO_BAR PPC_BIT(6) +#define VAS_ENABLE_UWC_MMIO_BAR PPC_BIT(7) +#define VAS_ENABLE_RMA_MMIO_BAR PPC_BIT(8) +#define VAS_HMI_ACTIVE_MASK PPC_BIT(58) +#define VAS_RG_IDLE_MASK PPC_BIT(59) + +/* Some PowerBus Configuration Register 0 Bits */ +#define VAS_CQ_SCOM_HANG_POLL_MAX PPC_BITMASK(7, 10) +#define VAS_CQ_SCOM_HANG_NX_MAX PPC_BITMASK(15, 18) + +#define VAS_RMA_BAR_ADDR_MASK PPC_BITMASK(8, 51) +#define VAS_RMA_BAMR_ADDR_MASK PPC_BITMASK(8, 51) + +#endif diff --git a/roms/skiboot/include/vpd.h b/roms/skiboot/include/vpd.h new file mode 100644 index 000000000..cdfc73a45 --- /dev/null +++ b/roms/skiboot/include/vpd.h @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __VPD_H +#define __VPD_H + +struct machine_info { + const char *mtm; + const char *name; +}; + +const struct machine_info *machine_info_lookup(const char *mtm); + +const void *vpd_find_keyword(const void *rec, size_t rec_sz, + const char *kw, uint8_t *kw_size); + +const void *vpd_find_record(const void *vpd, size_t vpd_size, + const char *record, size_t *sz); + +const void *vpd_find(const void *vpd, size_t vpd_size, + const char *record, const char *keyword, + uint8_t *sz); + +bool vpd_valid(const void *vvpd, size_t vpd_size); + +/* Add model property to dt_root */ +void add_dtb_model(void); + +#define VPD_LOAD_LXRN_VINI 0xff + + +#endif /* __VPD_H */ diff --git a/roms/skiboot/include/xive-p9-regs.h b/roms/skiboot/include/xive-p9-regs.h new file mode 100644 index 000000000..fff341cca --- /dev/null +++ b/roms/skiboot/include/xive-p9-regs.h @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * XIVE: eXternal Interrupt Virtualization Engine. POWER9 interrupt + * controller + * + * Copyright (c) 2016-2019, IBM Corporation. + */ +#ifndef XIVE_P9_REGS_H +#define XIVE_P9_REGS_H + +#include <xive-regs.h> + +/* IC register offsets */ +#define CQ_SWI_CMD_HIST 0x020 +#define CQ_SWI_CMD_POLL 0x028 +#define CQ_SWI_CMD_BCAST 0x030 +#define CQ_SWI_CMD_ASSIGN 0x038 +#define CQ_SWI_CMD_BLK_UPD 0x040 +#define CQ_SWI_RSP 0x048 +#define X_CQ_CFG_PB_GEN 0x0a +#define CQ_CFG_PB_GEN 0x050 +#define CQ_INT_ADDR_OPT PPC_BITMASK(14,15) +#define X_CQ_IC_BAR 0x10 +#define X_CQ_MSGSND 0x0b +#define CQ_MSGSND 0x058 +#define CQ_CNPM_SEL 0x078 +#define CQ_IC_BAR 0x080 +#define CQ_IC_BAR_VALID PPC_BIT(0) +#define CQ_IC_BAR_64K PPC_BIT(1) +#define X_CQ_TM1_BAR 0x12 +#define CQ_TM1_BAR 0x90 +#define X_CQ_TM2_BAR 0x014 +#define CQ_TM2_BAR 0x0a0 +#define CQ_TM_BAR_VALID PPC_BIT(0) +#define CQ_TM_BAR_64K PPC_BIT(1) +#define X_CQ_PC_BAR 0x16 +#define CQ_PC_BAR 0x0b0 +#define CQ_PC_BAR_VALID PPC_BIT(0) +#define X_CQ_PC_BARM 0x17 +#define CQ_PC_BARM 0x0b8 +#define CQ_PC_BARM_MASK PPC_BITMASK(26,38) +#define X_CQ_VC_BAR 0x18 +#define CQ_VC_BAR 0x0c0 +#define CQ_VC_BAR_VALID PPC_BIT(0) +#define X_CQ_VC_BARM 0x19 +#define CQ_VC_BARM 0x0c8 +#define CQ_VC_BARM_MASK PPC_BITMASK(21,37) +#define X_CQ_TAR 0x1e +#define CQ_TAR 0x0f0 +#define CQ_TAR_TBL_AUTOINC PPC_BIT(0) +#define CQ_TAR_TSEL_BLK PPC_BIT(12) +#define CQ_TAR_TSEL_MIG PPC_BIT(13) +#define CQ_TAR_TSEL_VDT PPC_BIT(14) +#define CQ_TAR_TSEL_EDT PPC_BIT(15) +#define X_CQ_TDR 0x1f +#define CQ_TDR 0x0f8 +#define X_CQ_PBI_CTL 0x20 +#define CQ_PBI_CTL 0x100 +#define CQ_PBI_PC_64K PPC_BIT(5) +#define CQ_PBI_VC_64K PPC_BIT(6) +#define CQ_PBI_LNX_TRIG PPC_BIT(7) +#define CQ_PBI_FORCE_TM_LOCAL PPC_BIT(22) +#define CQ_PBO_CTL 0x108 +#define CQ_AIB_CTL 0x110 +#define X_CQ_RST_CTL 0x23 +#define CQ_RST_CTL 0x118 +#define X_CQ_FIRMASK 0x33 +#define CQ_FIRMASK 0x198 +#define CQ_FIR_PB_RCMDX_CI_ERR1 PPC_BIT(19) +#define CQ_FIR_VC_INFO_ERROR_0_1 PPC_BITMASK(62,63) +#define X_CQ_FIRMASK_AND 0x34 +#define CQ_FIRMASK_AND 0x1a0 +#define X_CQ_FIRMASK_OR 0x35 +#define CQ_FIRMASK_OR 0x1a8 + +/* PC LBS1 register offsets */ +#define X_PC_TCTXT_CFG 0x100 +#define PC_TCTXT_CFG 0x400 +#define PC_TCTXT_CFG_BLKGRP_EN PPC_BIT(0) +#define PC_TCTXT_CFG_TARGET_EN PPC_BIT(1) +#define PC_TCTXT_CFG_LGS_EN PPC_BIT(2) +#define PC_TCTXT_CFG_STORE_ACK PPC_BIT(3) +#define PC_TCTXT_CFG_FUSE_CORE_EN PPC_BIT(4) +#define PC_TCTXT_CFG_HARD_CHIPID_BLK PPC_BIT(8) +#define PC_TCTXT_CHIPID_OVERRIDE PPC_BIT(9) +#define PC_TCTXT_CHIPID PPC_BITMASK(12,15) +#define PC_TCTXT_INIT_AGE PPC_BITMASK(30,31) +#define X_PC_TCTXT_TRACK 0x101 +#define PC_TCTXT_TRACK 0x408 +#define PC_TCTXT_TRACK_EN PPC_BIT(0) +#define X_PC_TCTXT_INDIR0 0x104 +#define PC_TCTXT_INDIR0 0x420 +#define PC_TCTXT_INDIR_VALID PPC_BIT(0) +#define PC_TCTXT_INDIR_THRDID PPC_BITMASK(9,15) +#define X_PC_TCTXT_INDIR1 0x105 +#define PC_TCTXT_INDIR1 0x428 +#define X_PC_TCTXT_INDIR2 0x106 +#define PC_TCTXT_INDIR2 0x430 +#define X_PC_TCTXT_INDIR3 0x107 +#define PC_TCTXT_INDIR3 0x438 +#define X_PC_THREAD_EN_REG0 0x108 +#define PC_THREAD_EN_REG0 0x440 +#define X_PC_THREAD_EN_REG0_SET 0x109 +#define PC_THREAD_EN_REG0_SET 0x448 +#define X_PC_THREAD_EN_REG0_CLR 0x10a +#define PC_THREAD_EN_REG0_CLR 0x450 +#define X_PC_THREAD_EN_REG1 0x10c +#define PC_THREAD_EN_REG1 0x460 +#define X_PC_THREAD_EN_REG1_SET 0x10d +#define PC_THREAD_EN_REG1_SET 0x468 +#define X_PC_THREAD_EN_REG1_CLR 0x10e +#define PC_THREAD_EN_REG1_CLR 0x470 +#define X_PC_GLOBAL_CONFIG 0x110 +#define PC_GLOBAL_CONFIG 0x480 +#define PC_GCONF_INDIRECT PPC_BIT(32) +#define PC_GCONF_CHIPID_OVR PPC_BIT(40) +#define PC_GCONF_CHIPID PPC_BITMASK(44,47) +#define X_PC_VSD_TABLE_ADDR 0x111 +#define PC_VSD_TABLE_ADDR 0x488 +#define X_PC_VSD_TABLE_DATA 0x112 +#define PC_VSD_TABLE_DATA 0x490 +#define X_PC_AT_KILL 0x116 +#define PC_AT_KILL 0x4b0 +#define PC_AT_KILL_VALID PPC_BIT(0) +#define PC_AT_KILL_BLOCK_ID PPC_BITMASK(27,31) +#define PC_AT_KILL_OFFSET PPC_BITMASK(48,60) +#define X_PC_AT_KILL_MASK 0x117 +#define PC_AT_KILL_MASK 0x4b8 + +/* PC LBS2 register offsets */ +#define X_PC_VPC_CACHE_ENABLE 0x161 +#define PC_VPC_CACHE_ENABLE 0x708 +#define PC_VPC_CACHE_EN_MASK PPC_BITMASK(0,31) +#define X_PC_VPC_SCRUB_TRIG 0x162 +#define PC_VPC_SCRUB_TRIG 0x710 +#define X_PC_VPC_SCRUB_MASK 0x163 +#define PC_VPC_SCRUB_MASK 0x718 +#define PC_SCRUB_VALID PPC_BIT(0) +#define PC_SCRUB_WANT_DISABLE PPC_BIT(1) +#define PC_SCRUB_WANT_INVAL PPC_BIT(2) +#define PC_SCRUB_BLOCK_ID PPC_BITMASK(27,31) +#define PC_SCRUB_OFFSET PPC_BITMASK(45,63) +#define X_PC_VPC_CWATCH_SPEC 0x167 +#define PC_VPC_CWATCH_SPEC 0x738 +#define PC_VPC_CWATCH_CONFLICT PPC_BIT(0) +#define PC_VPC_CWATCH_FULL PPC_BIT(8) +#define PC_VPC_CWATCH_BLOCKID PPC_BITMASK(27,31) +#define PC_VPC_CWATCH_OFFSET PPC_BITMASK(45,63) +#define X_PC_VPC_CWATCH_DAT0 0x168 +#define PC_VPC_CWATCH_DAT0 0x740 +#define X_PC_VPC_CWATCH_DAT1 0x169 +#define PC_VPC_CWATCH_DAT1 0x748 +#define X_PC_VPC_CWATCH_DAT2 0x16a +#define PC_VPC_CWATCH_DAT2 0x750 +#define X_PC_VPC_CWATCH_DAT3 0x16b +#define PC_VPC_CWATCH_DAT3 0x758 +#define X_PC_VPC_CWATCH_DAT4 0x16c +#define PC_VPC_CWATCH_DAT4 0x760 +#define X_PC_VPC_CWATCH_DAT5 0x16d +#define PC_VPC_CWATCH_DAT5 0x768 +#define X_PC_VPC_CWATCH_DAT6 0x16e +#define PC_VPC_CWATCH_DAT6 0x770 +#define X_PC_VPC_CWATCH_DAT7 0x16f +#define PC_VPC_CWATCH_DAT7 0x778 + +/* VC0 register offsets */ +#define X_VC_GLOBAL_CONFIG 0x200 +#define VC_GLOBAL_CONFIG 0x800 +#define VC_GCONF_INDIRECT PPC_BIT(32) +#define X_VC_VSD_TABLE_ADDR 0x201 +#define VC_VSD_TABLE_ADDR 0x808 +#define X_VC_VSD_TABLE_DATA 0x202 +#define VC_VSD_TABLE_DATA 0x810 +#define VC_IVE_ISB_BLOCK_MODE 0x818 +#define VC_EQD_BLOCK_MODE 0x820 +#define VC_VPS_BLOCK_MODE 0x828 +#define X_VC_IRQ_CONFIG_IPI 0x208 +#define VC_IRQ_CONFIG_IPI 0x840 +#define VC_IRQ_CONFIG_MEMB_EN PPC_BIT(45) +#define VC_IRQ_CONFIG_MEMB_SZ PPC_BITMASK(46,51) +#define VC_IRQ_CONFIG_HW 0x848 +#define VC_IRQ_CONFIG_CASCADE1 0x850 +#define VC_IRQ_CONFIG_CASCADE2 0x858 +#define VC_IRQ_CONFIG_REDIST 0x860 +#define VC_IRQ_CONFIG_IPI_CASC 0x868 +#define X_VC_AIB_TX_ORDER_TAG2 0x22d +#define VC_AIB_TX_ORDER_TAG2_REL_TF PPC_BIT(20) +#define VC_AIB_TX_ORDER_TAG2 0x890 +#define X_VC_AT_MACRO_KILL 0x23e +#define VC_AT_MACRO_KILL 0x8b0 +#define X_VC_AT_MACRO_KILL_MASK 0x23f +#define VC_AT_MACRO_KILL_MASK 0x8b8 +#define VC_KILL_VALID PPC_BIT(0) +#define VC_KILL_TYPE PPC_BITMASK(14,15) +#define VC_KILL_IRQ 0 +#define VC_KILL_IVC 1 +#define VC_KILL_SBC 2 +#define VC_KILL_EQD 3 +#define VC_KILL_BLOCK_ID PPC_BITMASK(27,31) +#define VC_KILL_OFFSET PPC_BITMASK(48,60) +#define X_VC_EQC_CACHE_ENABLE 0x211 +#define VC_EQC_CACHE_ENABLE 0x908 +#define VC_EQC_CACHE_EN_MASK PPC_BITMASK(0,15) +#define X_VC_EQC_SCRUB_TRIG 0x212 +#define VC_EQC_SCRUB_TRIG 0x910 +#define X_VC_EQC_SCRUB_MASK 0x213 +#define VC_EQC_SCRUB_MASK 0x918 +#define X_VC_EQC_CWATCH_SPEC 0x215 +#define VC_EQC_CONFIG 0x920 +#define X_VC_EQC_CONFIG 0x214 +#define VC_EQC_CONF_SYNC_IPI PPC_BIT(32) +#define VC_EQC_CONF_SYNC_HW PPC_BIT(33) +#define VC_EQC_CONF_SYNC_ESC1 PPC_BIT(34) +#define VC_EQC_CONF_SYNC_ESC2 PPC_BIT(35) +#define VC_EQC_CONF_SYNC_REDI PPC_BIT(36) +#define VC_EQC_CONF_EQP_INTERLEAVE PPC_BIT(38) +#define VC_EQC_CONF_ENABLE_END_s_BIT PPC_BIT(39) +#define VC_EQC_CONF_ENABLE_END_u_BIT PPC_BIT(40) +#define VC_EQC_CONF_ENABLE_END_c_BIT PPC_BIT(41) +#define VC_EQC_CONF_ENABLE_MORE_QSZ PPC_BIT(42) +#define VC_EQC_CONF_SKIP_ESCALATE PPC_BIT(43) +#define VC_EQC_CWATCH_SPEC 0x928 +#define VC_EQC_CWATCH_CONFLICT PPC_BIT(0) +#define VC_EQC_CWATCH_FULL PPC_BIT(8) +#define VC_EQC_CWATCH_BLOCKID PPC_BITMASK(28,31) +#define VC_EQC_CWATCH_OFFSET PPC_BITMASK(40,63) +#define X_VC_EQC_CWATCH_DAT0 0x216 +#define VC_EQC_CWATCH_DAT0 0x930 +#define X_VC_EQC_CWATCH_DAT1 0x217 +#define VC_EQC_CWATCH_DAT1 0x938 +#define X_VC_EQC_CWATCH_DAT2 0x218 +#define VC_EQC_CWATCH_DAT2 0x940 +#define X_VC_EQC_CWATCH_DAT3 0x219 +#define VC_EQC_CWATCH_DAT3 0x948 +#define X_VC_IVC_SCRUB_TRIG 0x222 +#define VC_IVC_SCRUB_TRIG 0x990 +#define X_VC_IVC_SCRUB_MASK 0x223 +#define VC_IVC_SCRUB_MASK 0x998 +#define X_VC_SBC_SCRUB_TRIG 0x232 +#define VC_SBC_SCRUB_TRIG 0xa10 +#define X_VC_SBC_SCRUB_MASK 0x233 +#define VC_SBC_SCRUB_MASK 0xa18 +#define VC_SCRUB_VALID PPC_BIT(0) +#define VC_SCRUB_WANT_DISABLE PPC_BIT(1) +#define VC_SCRUB_WANT_INVAL PPC_BIT(2) /* EQC and SBC only */ +#define VC_SCRUB_BLOCK_ID PPC_BITMASK(28,31) +#define VC_SCRUB_OFFSET PPC_BITMASK(40,63) +#define X_VC_IVC_CACHE_ENABLE 0x221 +#define VC_IVC_CACHE_ENABLE 0x988 +#define VC_IVC_CACHE_EN_MASK PPC_BITMASK(0,15) +#define X_VC_SBC_CACHE_ENABLE 0x231 +#define VC_SBC_CACHE_ENABLE 0xa08 +#define VC_SBC_CACHE_EN_MASK PPC_BITMASK(0,15) +#define VC_IVC_CACHE_SCRUB_TRIG 0x990 +#define VC_IVC_CACHE_SCRUB_MASK 0x998 +#define VC_SBC_CACHE_ENABLE 0xa08 +#define VC_SBC_CACHE_SCRUB_TRIG 0xa10 +#define VC_SBC_CACHE_SCRUB_MASK 0xa18 +#define VC_SBC_CONFIG 0xa20 +#define X_VC_SBC_CONFIG 0x234 +#define VC_SBC_CONF_CPLX_CIST PPC_BIT(44) +#define VC_SBC_CONF_CIST_BOTH PPC_BIT(45) +#define VC_SBC_CONF_NO_UPD_PRF PPC_BIT(59) + +/* VC1 register offsets */ + +/* VSD Table address register definitions (shared) */ +#define VST_ADDR_AUTOINC PPC_BIT(0) +#define VST_TABLE_SELECT PPC_BITMASK(13,15) +#define VST_TSEL_IVT 0 +#define VST_TSEL_SBE 1 +#define VST_TSEL_EQDT 2 +#define VST_TSEL_VPDT 3 +#define VST_TSEL_IRQ 4 /* VC only */ +#define VST_TABLE_OFFSET PPC_BITMASK(27,31) + +/* Number of queue overflow pages */ +#define VC_QUEUE_OVF_COUNT 6 + +/* Bits in a VSD entry. + * + * Note: the address is naturally aligned, we don't use a PPC_BITMASK, + * but just a mask to apply to the address before OR'ing it in. + * + * Note: VSD_FIRMWARE is a SW bit ! It hijacks an unused bit in the + * VSD and is only meant to be used in indirect mode ! + */ +#define VSD_MODE PPC_BITMASK(0,1) +#define VSD_MODE_SHARED 1 +#define VSD_MODE_EXCLUSIVE 2 +#define VSD_MODE_FORWARD 3 +#define VSD_ADDRESS_MASK 0x0ffffffffffff000ull +#define VSD_MIGRATION_REG PPC_BITMASK(52,55) +#define VSD_INDIRECT PPC_BIT(56) +#define VSD_TSIZE PPC_BITMASK(59,63) +#define VSD_FIRMWARE PPC_BIT(2) /* Read warning above */ + +/* + * Definition of the XIVE in-memory tables + */ + +/* IVE/EAS + * + * One per interrupt source. Targets that interrupt to a given EQ + * and provides the corresponding logical interrupt number (EQ data) + * + * We also map this structure to the escalation descriptor inside + * an EQ, though in that case the valid and masked bits are not used. + */ +struct xive_ive { + /* Use a single 64-bit definition to make it easier to + * perform atomic updates + */ + __be64 w; +#define IVE_VALID PPC_BIT(0) +#define IVE_EQ_BLOCK PPC_BITMASK(4,7) /* Destination EQ block# */ +#define IVE_EQ_INDEX PPC_BITMASK(8,31) /* Destination EQ index */ +#define IVE_MASKED PPC_BIT(32) /* Masked */ +#define IVE_EQ_DATA PPC_BITMASK(33,63) /* Data written to the EQ */ +}; + +/* EQ */ +struct xive_eq { + __be32 w0; +#define EQ_W0_VALID PPC_BIT32(0) /* "v" bit */ +#define EQ_W0_ENQUEUE PPC_BIT32(1) /* "q" bit */ +#define EQ_W0_UCOND_NOTIFY PPC_BIT32(2) /* "n" bit */ +#define EQ_W0_BACKLOG PPC_BIT32(3) /* "b" bit */ +#define EQ_W0_PRECL_ESC_CTL PPC_BIT32(4) /* "p" bit */ +#define EQ_W0_ESCALATE_CTL PPC_BIT32(5) /* "e" bit */ +#define EQ_W0_UNCOND_ESCALATE PPC_BIT32(6) /* "u" bit - DD2.0 */ +#define EQ_W0_SILENT_ESCALATE PPC_BIT32(7) /* "s" bit - DD2.0 */ +#define EQ_W0_QSIZE PPC_BITMASK32(12,15) +#define EQ_W0_SW0 PPC_BIT32(16) +#define EQ_W0_FIRMWARE EQ_W0_SW0 /* Owned by FW */ +#define EQ_QSIZE_4K 0 +#define EQ_QSIZE_64K 4 +#define EQ_W0_HWDEP PPC_BITMASK32(24,31) + __be32 w1; +#define EQ_W1_ESn PPC_BITMASK32(0,1) +#define EQ_W1_ESn_P PPC_BIT32(0) +#define EQ_W1_ESn_Q PPC_BIT32(1) +#define EQ_W1_ESe PPC_BITMASK32(2,3) +#define EQ_W1_ESe_P PPC_BIT32(2) +#define EQ_W1_ESe_Q PPC_BIT32(3) +#define EQ_W1_ES PPC_BITMASK32(0,3) +#define EQ_W1_GENERATION PPC_BIT32(9) +#define EQ_W1_PAGE_OFF PPC_BITMASK32(10,31) + __be32 w2; +#define EQ_W2_MIGRATION_REG PPC_BITMASK32(0,3) +#define EQ_W2_OP_DESC_HI PPC_BITMASK32(4,31) + __be32 w3; +#define EQ_W3_OP_DESC_LO PPC_BITMASK32(0,31) + __be32 w4; +#define EQ_W4_ESC_EQ_BLOCK PPC_BITMASK32(4,7) +#define EQ_W4_ESC_EQ_INDEX PPC_BITMASK32(8,31) + __be32 w5; +#define EQ_W5_ESC_EQ_DATA PPC_BITMASK32(1,31) + __be32 w6; +#define EQ_W6_FORMAT_BIT PPC_BIT32(8) +#define EQ_W6_NVT_BLOCK PPC_BITMASK32(9,12) +#define EQ_W6_NVT_INDEX PPC_BITMASK32(13,31) + __be32 w7; +#define EQ_W7_F0_IGNORE PPC_BIT32(0) +#define EQ_W7_F0_BLK_GROUPING PPC_BIT32(1) +#define EQ_W7_F0_PRIORITY PPC_BITMASK32(8,15) +#define EQ_W7_F1_WAKEZ PPC_BIT32(0) +#define EQ_W7_F1_LOG_SERVER_ID PPC_BITMASK32(1,31) +}; + +/* VP */ +struct xive_vp { + __be32 w0; +#define VP_W0_VALID PPC_BIT32(0) + __be32 w1; + __be32 w2; + __be32 w3; + __be32 w4; + __be32 w5; + __be32 w6; + __be32 w7; + __be32 w8; +#define VP_W8_GRP_VALID PPC_BIT32(0) + __be32 w9; + __be32 wa; + __be32 wb; + __be32 wc; + __be32 wd; + __be32 we; + __be32 wf; +}; + +#endif /* XIVE_P9_REGS_H */ diff --git a/roms/skiboot/include/xive-regs.h b/roms/skiboot/include/xive-regs.h new file mode 100644 index 000000000..702e5b152 --- /dev/null +++ b/roms/skiboot/include/xive-regs.h @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * XIVE: eXternal Interrupt Virtualization Engine. POWER9 interrupt + * controller + * + * Copyright (c) 2016-2019, IBM Corporation. + */ +#ifndef XIVE_REGS_H +#define XIVE_REGS_H + +static inline uint64_t xive_get_field64(uint64_t mask, beint64_t word) +{ + return (be64_to_cpu(word) & mask) >> MASK_TO_LSH(mask); +} + +static inline beint64_t xive_set_field64(uint64_t mask, beint64_t word, + uint64_t value) +{ + uint64_t tmp = (be64_to_cpu(word) & ~mask) | + ((value << MASK_TO_LSH(mask)) & mask); + return cpu_to_be64(tmp); +} + +static inline uint32_t xive_get_field32(uint32_t mask, beint32_t word) +{ + return (be32_to_cpu(word) & mask) >> MASK_TO_LSH(mask); +} + +static inline beint32_t xive_set_field32(uint32_t mask, beint32_t word, + uint32_t value) +{ + uint32_t tmp = (be32_to_cpu(word) & ~mask) | + ((value << MASK_TO_LSH(mask)) & mask); + return cpu_to_be32(tmp); +} + +/* + * TM registers are special, see below + */ + +/* TM register offsets */ +#define TM_QW0_USER 0x000 /* All rings */ +#define TM_QW1_OS 0x010 /* Ring 0..2 */ +#define TM_QW2_HV_POOL 0x020 /* Ring 0..1 */ +#define TM_QW3_HV_PHYS 0x030 /* Ring 0..1 */ + +/* Byte offsets inside a QW QW0 QW1 QW2 QW3 */ +#define TM_NSR 0x0 /* + + - + */ +#define TM_CPPR 0x1 /* - + - + */ +#define TM_IPB 0x2 /* - + + + */ +#define TM_LSMFB 0x3 /* - + + + */ +#define TM_ACK_CNT 0x4 /* - + - - */ +#define TM_INC 0x5 /* - + - + */ +#define TM_AGE 0x6 /* - + - + */ +#define TM_PIPR 0x7 /* - + - + */ + +/* QW word 2 contains the valid bit at the top and other fields + * depending on the QW + */ +#define TM_WORD2 0x8 +#define TM_QW0W2_VU PPC_BIT32(0) +#define TM_QW0W2_LOGIC_SERV PPC_BITMASK32(1,31) // XX 2,31 ? +#define TM_QW1W2_VO PPC_BIT32(0) +#define TM_QW1W2_OS_CAM PPC_BITMASK32(8,31) +#define TM_QW2W2_VP PPC_BIT32(0) +#define TM_QW2W2_POOL_CAM PPC_BITMASK32(8,31) +#define TM_QW3W2_VT PPC_BIT32(0) +#define TM_QW3W2_LP PPC_BIT32(6) +#define TM_QW3W2_LE PPC_BIT32(7) +#define TM_QW3W2_T PPC_BIT32(31) + +/* In addition to normal loads to "peek" and writes (only when invalid) + * using 4 and 8 bytes accesses, the above registers support these + * "special" byte operations: + * + * - Byte load from QW0[NSR] - User level NSR (EBB) + * - Byte store to QW0[NSR] - User level NSR (EBB) + * - Byte load/store to QW1[CPPR] and QW3[CPPR] - CPPR access + * - Byte load from QW3[TM_WORD2] - Read VT||00000||LP||LE on thrd 0 + * otherwise VT||0000000 + * - Byte store to QW3[TM_WORD2] - Set VT bit (and LP/LE if present) + * + * Then we have all these "special" CI ops at these offset that trigger + * all sorts of side effects: + * + * We can OR'in these a cache line index from 0...3 (ie, 0, 0x80, 0x100, 0x180) + * to select a specific snooper. 0 is pretty busy so 0x80 or 0x100 is recommended + * XXX TODO. add that and find way to tell KVM about it. + */ +#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg*/ +#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */ +#define TM_SPC_PUSH_USR_CTX 0x808 /* Store32 Push/Validate user context */ +#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user context */ +#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */ +#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS context to reg */ +#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate Pool context to reg*/ +#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */ +#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd line */ +#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line */ +#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even line */ +#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line */ +/* XXX more... */ + +/* NSR fields for the various QW ack types */ +#define TM_QW0_NSR_EB PPC_BIT8(0) +#define TM_QW1_NSR_EO PPC_BIT8(0) +#define TM_QW3_NSR_HE PPC_BITMASK8(0,1) +#define TM_QW3_NSR_HE_NONE 0 +#define TM_QW3_NSR_HE_POOL 1 +#define TM_QW3_NSR_HE_PHYS 2 +#define TM_QW3_NSR_HE_LSI 3 +#define TM_QW3_NSR_I PPC_BIT8(2) +#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3,7) + +/* + * "magic" Event State Buffer (ESB) MMIO offsets. + * + * The following offsets into the ESB MMIO allow to read or manipulate + * the PQ bits. They must be used with an 8-byte load instruction. + * They all return the previous state of the interrupt (atomically). + * + * Additionally, some ESB pages support doing an EOI via a store and + * some ESBs support doing a trigger via a separate trigger page. + */ +#define XIVE_ESB_STORE_TRIGGER 0x000 /* Store in range 0x000-0x3FF */ +#define XIVE_ESB_STORE_EOI 0x400 /* Store */ +#define XIVE_ESB_LOAD_EOI 0x000 /* Load */ +#define XIVE_ESB_GET 0x800 /* Load */ +#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */ +#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */ +#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */ +#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */ + +#endif /* XIVE_REGS_H__ */ diff --git a/roms/skiboot/include/xive.h b/roms/skiboot/include/xive.h new file mode 100644 index 000000000..1a8a2e027 --- /dev/null +++ b/roms/skiboot/include/xive.h @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * XIVE: eXternal Interrupt Virtualization Engine. POWER9 interrupt + * controller + * + * Copyright (c) 2016-2019, IBM Corporation. + */ + +#ifndef XIVE_H +#define XIVE_H + +/* Internal APIs to other modules */ + +/* IRQ allocators return this on failure */ +#define XIVE_IRQ_ERROR 0xffffffff + +void init_xive(void); +int64_t xive_reset(void); + +/* Allocate a chunk of HW sources */ +uint32_t xive_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align); +/* Allocate a chunk of IPI sources */ +uint32_t xive_alloc_ipi_irqs(uint32_t chip_id, uint32_t count, uint32_t align); + +/* Get notification port address for a HW source entity */ +#define XIVE_HW_SRC_PHBn(__n) (__n) +#define XIVE_HW_SRC_PSI 8 + +uint64_t xive_get_notify_port(uint32_t chip_id, uint32_t ent); +__attrconst uint32_t xive_get_notify_base(uint32_t girq); + +/* XIVE feature flag to de/activate store EOI */ +#define XIVE_STORE_EOI_ENABLED 0 + +/* Internal IRQ flags */ +#define XIVE_SRC_TRIGGER_PAGE 0x01 /* Trigger page exist (either separate + * or not, so different from the OPAL + * flag which is only set when the + * trigger page is separate). + */ +#define XIVE_SRC_EOI_PAGE1 0x02 /* EOI on the second page */ +#define XIVE_SRC_STORE_EOI 0x04 /* EOI using stores supported */ +#define XIVE_SRC_LSI 0x08 /* Interrupt is an LSI */ + +struct irq_source_ops; +void xive_register_hw_source(uint32_t base, uint32_t count, uint32_t shift, + void *mmio, uint32_t flags, void *data, + const struct irq_source_ops *ops); +void xive_register_ipi_source(uint32_t base, uint32_t count, void *data, + const struct irq_source_ops *ops); + +void xive_cpu_callin(struct cpu_thread *cpu); + +/* Get the trigger page address for an interrupt allocated with + * xive_alloc_ipi_irqs() + */ +void *xive_get_trigger_port(uint32_t girq); + +/* To be used by PSI to prevent asserted LSI to constantly re-fire */ +struct irq_source; +void xive_source_mask(struct irq_source *is, uint32_t isn); + +void xive_cpu_reset(void); +void xive_late_init(void); + +/* + * POWER10 + */ + +/* + * StoreEOI requires the OS to enforce load-after-store ordering and + * the PHB5 should be configured in Address-based trigger mode with PQ + * state bit offloading. + */ +#define XIVE2_STORE_EOI_ENABLED xive2_cap_store_eoi() + +void xive2_init(void); +bool xive2_cap_phb_pq_disable(void); +bool xive2_cap_phb_abt(void); +bool xive2_cap_store_eoi(void); +int64_t xive2_reset(void); + +uint32_t xive2_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align); +uint32_t xive2_alloc_ipi_irqs(uint32_t chip_id, uint32_t count, uint32_t align); +uint64_t xive2_get_notify_port(uint32_t chip_id, uint32_t ent); +__attrconst uint32_t xive2_get_notify_base(uint32_t girq); +void xive2_register_hw_source(uint32_t base, uint32_t count, uint32_t shift, + void *mmio, uint32_t flags, void *data, + const struct irq_source_ops *ops); +void xive2_register_ipi_source(uint32_t base, uint32_t count, void *data, + const struct irq_source_ops *ops); +void xive2_register_esb_source(uint32_t base, uint32_t count); +uint64_t xive2_get_esb_base(uint32_t girq); +void xive2_cpu_callin(struct cpu_thread *cpu); +void *xive2_get_trigger_port(uint32_t girq); + +void xive2_source_mask(struct irq_source *is, uint32_t isn); + +void xive2_cpu_reset(void); +void xive2_late_init(void); + +#endif /* XIVE_H */ diff --git a/roms/skiboot/include/xive2-regs.h b/roms/skiboot/include/xive2-regs.h new file mode 100644 index 000000000..1f7a3e721 --- /dev/null +++ b/roms/skiboot/include/xive2-regs.h @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * XIVE2: eXternal Interrupt Virtualization Engine. POWER10 interrupt + * controller + * + * Copyright (c) 2019, IBM Corporation. + */ + +#ifndef XIVE2_REGS_H +#define XIVE2_REGS_H + +#include <xive-regs.h> + +/* + * CQ Common Queue (PowerBus bridge) Registers + */ + +/* XIVE Capabilities */ +#define X_CQ_XIVE_CAP 0x02 +#define CQ_XIVE_CAP 0x010 +#define CQ_XIVE_CAP_VERSION PPC_BITMASK(0,3) +/* 4:6 reserved */ +#define CQ_XIVE_CAP_USER_INT_PRIO PPC_BITMASK(8,9) +#define CQ_XIVE_CAP_USER_INT_PRIO_1 0 +#define CQ_XIVE_CAP_USER_INT_PRIO_1_2 1 +#define CQ_XIVE_CAP_USER_INT_PRIO_1_4 2 +#define CQ_XIVE_CAP_USER_INT_PRIO_1_8 3 +#define CQ_XIVE_CAP_VP_INT_PRIO PPC_BITMASK(10,11) +#define CQ_XIVE_CAP_VP_INT_PRIO_1_8 0 +#define CQ_XIVE_CAP_VP_INT_PRIO_2_8 1 +#define CQ_XIVE_CAP_VP_INT_PRIO_4_8 2 +#define CQ_XIVE_CAP_VP_INT_PRIO_8 3 +#define CQ_XIVE_CAP_BLOCK_ID_WIDTH PPC_BITMASK(12,13) +#define CQ_XIVE_CAP_VP_SAVE_RESTORE PPC_BIT(38) +#define CQ_XIVE_CAP_PHB_PQ_DISABLE PPC_BIT(56) +#define CQ_XIVE_CAP_PHB_ABT PPC_BIT(57) +#define CQ_XIVE_CAP_EXPLOITATION_MODE PPC_BIT(58) +#define CQ_XIVE_CAP_STORE_EOI PPC_BIT(59) +/* 62:63 reserved */ + +/* XIVE Configuration */ +#define X_CQ_XIVE_CFG 0x03 +#define CQ_XIVE_CFG 0x018 + +/* 0:7 reserved */ +#define CQ_XIVE_CFG_USER_INT_PRIO PPC_BITMASK(8,9) +#define CQ_XIVE_CFG_VP_INT_PRIO PPC_BITMASK(10,11) +#define CQ_XIVE_CFG_INT_PRIO_1 0 +#define CQ_XIVE_CFG_INT_PRIO_2 1 +#define CQ_XIVE_CFG_INT_PRIO_4 2 +#define CQ_XIVE_CFG_INT_PRIO_8 3 +#define CQ_XIVE_CFG_BLOCK_ID_WIDTH PPC_BITMASK(12,13) +#define CQ_XIVE_CFG_BLOCK_ID_4BITS 0 +#define CQ_XIVE_CFG_BLOCK_ID_5BITS 1 +#define CQ_XIVE_CFG_BLOCK_ID_6BITS 2 +#define CQ_XIVE_CFG_BLOCK_ID_7BITS 3 +#define CQ_XIVE_CFG_HYP_HARD_RANGE PPC_BITMASK(14,15) +#define CQ_XIVE_CFG_THREADID_7BITS 0 +#define CQ_XIVE_CFG_THREADID_8BITS 1 +#define CQ_XIVE_CFG_THREADID_9BITS 2 +#define CQ_XIVE_CFG_THREADID_10BITs 3 +#define CQ_XIVE_CFG_HYP_HARD_BLKID_OVERRIDE PPC_BIT(16) +#define CQ_XIVE_CFG_HYP_HARD_BLOCK_ID PPC_BITMASK(17,23) + +#define CQ_XIVE_CFG_GEN1_TIMA_OS PPC_BIT(24) +#define CQ_XIVE_CFG_GEN1_TIMA_HYP PPC_BIT(25) +#define CQ_XIVE_CFG_GEN1_TIMA_HYP_BLK0 PPC_BIT(26) /* 0 if bit[25]=0 */ +#define CQ_XIVE_CFG_GEN1_TIMA_CROWD_DIS PPC_BIT(27) /* 0 if bit[25]=0 */ +#define CQ_XIVE_CFG_GEN1_END_ESX PPC_BIT(28) /* END ESx stores + are dropped */ +#define CQ_XIVE_CFG_EN_VP_SAVE_RESTORE PPC_BIT(38) /* 0 if bit[25]=1 */ +#define CQ_XIVE_CFG_EN_VP_SAVE_REST_STRICT PPC_BIT(39) /* 0 if bit[25]=1 */ + +#define CQ_XIVE_CFG_EN_VP_SAVE_RESTORE PPC_BIT(38) /* 0 if bit[25]=1 */ + +/* Interrupt Controller Base Address Register - 512 pages (32M) */ +#define X_CQ_IC_BAR 0x08 +#define CQ_IC_BAR 0x040 +#define CQ_IC_BAR_VALID PPC_BIT(0) +#define CQ_IC_BAR_64K PPC_BIT(1) +/* 2:7 reserved */ +#define CQ_IC_BAR_ADDR PPC_BITMASK(8,42) +/* 43:63 reserved */ + +/* Thread Management Base Address Register - 4 pages */ +#define X_CQ_TM_BAR 0x09 +#define CQ_TM_BAR 0x048 +#define CQ_TM_BAR_VALID PPC_BIT(0) +#define CQ_TM_BAR_64K PPC_BIT(1) +#define CQ_TM_BAR_ADDR PPC_BITMASK(8,49) + +/* ESB Base Address Register */ +#define X_CQ_ESB_BAR 0x0A +#define CQ_ESB_BAR 0x050 +#define CQ_BAR_VALID PPC_BIT(0) +#define CQ_BAR_64K PPC_BIT(1) +/* 2:7 reserved */ +#define CQ_BAR_ADDR PPC_BITMASK(8,39) +#define CQ_BAR_SET_DIV PPC_BITMASK(56,58) +#define CQ_BAR_RANGE PPC_BITMASK(59,63) + /* 0 (16M) - 16 (16T) */ + +/* END Base Address Register */ +#define X_CQ_END_BAR 0x0B +#define CQ_END_BAR 0x058 + +/* NVPG Base Address Register */ +#define X_CQ_NVPG_BAR 0x0C +#define CQ_NVPG_BAR 0x060 + +/* NVC Base Address Register */ +#define X_CQ_NVC_BAR 0x0D +#define CQ_NVC_BAR 0x068 + +/* Table Address Register */ +#define X_CQ_TAR 0x0E +#define CQ_TAR 0x070 +#define CQ_TAR_AUTOINC PPC_BIT(0) +#define CQ_TAR_SELECT PPC_BITMASK(12,15) +#define CQ_TAR_ESB 0 /* 0 - 15 */ +#define CQ_TAR_END 2 /* 0 - 15 */ +#define CQ_TAR_NVPG 3 /* 0 - 15 */ +#define CQ_TAR_NVC 5 /* 0 - 15 */ +#define CQ_TAR_ENTRY_SELECT PPC_BITMASK(28,31) + +/* Table Data Register */ +#define X_CQ_TDR 0x0F +#define CQ_TDR 0x078 +/* for the NVPG, NVC, ESB, END Set Translation Tables */ +#define CQ_TDR_VALID PPC_BIT(0) +#define CQ_TDR_BLOCK_ID PPC_BITMASK(60,63) + +/* + * Processor Cores Enabled for MsgSnd + * Identifies which of the 32 possible core chiplets are enabled and + * available to receive the MsgSnd command + */ +#define X_CQ_MSGSND 0x10 +#define CQ_MSGSND 0x080 + +/* Interrupt Unit Reset Control */ +#define X_CQ_RST_CTL 0x12 +#define CQ_RST_CTL 0x090 +#define CQ_RST_SYNC_RESET PPC_BIT(0) /* Write Only */ +#define CQ_RST_QUIESCE_PB PPC_BIT(1) /* RW */ +#define CQ_RST_MASTER_IDLE PPC_BIT(2) /* Read Only */ +#define CQ_RST_SAVE_IDLE PPC_BIT(3) /* Read Only */ +#define CQ_RST_PB_BAR_RESET PPC_BIT(4) /* Write Only */ + +/* PowerBus General Configuration */ +#define X_CQ_CFG_PB_GEN 0x14 +#define CQ_CFG_PB_GEN 0x0A0 + +/* FIR + * (And-Mask) + * (Or-Mask) + */ +#define X_CQ_FIR 0x30 +#define X_CQ_FIR_AND 0x31 +#define X_CQ_FIR_OR 0x32 +#define CQ_FIR 0x180 +#define CQ_FIR_AND 0x188 +#define CQ_FIR_OR 0x190 +#define CQ_FIR_PB_RCMDX_CI_ERR1 PPC_BIT(19) +#define CQ_FIR_VC_INFO_ERROR_0_2 PPC_BITMASK(61,63) + +/* FIR Mask + * (And-Mask) + * (Or-Mask) + */ +#define X_CQ_FIRMASK 0x33 +#define X_CQ_FIRMASK_AND 0x34 +#define X_CQ_FIRMASK_OR 0x35 +#define CQ_FIRMASK 0x198 +#define CQ_FIRMASK_AND 0x1A0 +#define CQ_FIRMASK_OR 0x1A8 + +/* + * VC0 + */ + +/* VSD table address */ +#define X_VC_VSD_TABLE_ADDR 0x100 +#define VC_VSD_TABLE_ADDR 0x000 +#define VC_VSD_TABLE_AUTOINC PPC_BIT(0) +#define VC_VSD_TABLE_SELECT PPC_BITMASK(12,15) +#define VC_VSD_TABLE_ADDRESS PPC_BITMASK(28,31) + +/* VSD table data */ +#define X_VC_VSD_TABLE_DATA 0x101 +#define VC_VSD_TABLE_DATA 0x008 + +/* AIB AT macro indirect kill */ +#define X_VC_AT_MACRO_KILL 0x102 +#define VC_AT_MACRO_KILL 0x010 +#define VC_AT_MACRO_KILL_VALID PPC_BIT(0) +#define VC_AT_MACRO_KILL_VSD PPC_BITMASK(12,15) +#define VC_AT_MACRO_KILL_BLOCK_ID PPC_BITMASK(28,31) +#define VC_AT_MACRO_KILL_OFFSET PPC_BITMASK(48,60) + +/* AIB AT macro indirect kill mask (same bit definitions) */ +#define X_VC_AT_MACRO_KILL_MASK 0x103 +#define VC_AT_MACRO_KILL_MASK 0x018 + +/* Remote IRQs and ERQs configuration [n] (n = 0:6) */ +#define X_VC_QUEUES_CFG_REM0 0x117 + +#define VC_QUEUES_CFG_REM0 0x0B8 +#define VC_QUEUES_CFG_MEMB_EN PPC_BIT(38) +#define VC_QUEUES_CFG_MEMB_SZ PPC_BITMASK(42,47) + +/* + * VC1 + */ + +/* ESBC cache flush control trigger */ +#define X_VC_ESBC_FLUSH_CTRL 0x140 +#define VC_ESBC_FLUSH_CTRL 0x200 +#define VC_ESBC_FLUSH_CTRL_POLL_VALID PPC_BIT(0) +#define VC_ESBC_FLUSH_CTRL_WANT_CACHE_DISABLE PPC_BIT(2) + +/* ESBC cache flush poll trigger */ +#define X_VC_ESBC_FLUSH_POLL 0x141 +#define VC_ESBC_FLUSH_POLL 0x208 +#define VC_ESBC_FLUSH_POLL_BLOCK_ID PPC_BITMASK(0,3) +#define VC_ESBC_FLUSH_POLL_OFFSET PPC_BITMASK(4,31) /* 28-bit */ +#define VC_ESBC_FLUSH_POLL_BLOCK_ID_MASK PPC_BITMASK(32,35) +#define VC_ESBC_FLUSH_POLL_OFFSET_MASK PPC_BITMASK(36,63) /* 28-bit */ + +/* ESBC configuration */ +#define X_VC_ESBC_CFG 0x148 +#define VC_ESBC_CFG 0x240 +#define VC_ESBC_CFG_HASH_ARRAY_ENABLE PPC_BIT(40) +#define VC_ESBC_CFG_HASH_STORE_MODE PPC_BITMASK(41,42) +#define VC_ESBC_CFG_SPLIT_MODE PPC_BIT(56) +#define VC_ESBC_CFG_MAX_ENTRIES_IN_MODIFIED PPC_BITMASK(59,63) + +/* EASC flush control register */ +#define X_VC_EASC_FLUSH_CTRL 0x160 +#define VC_EASC_FLUSH_CTRL 0x300 +#define VC_EASC_FLUSH_CTRL_POLL_VALID PPC_BIT(0) +#define VC_EASC_FLUSH_CTRL_WANT_CACHE_DISABLE PPC_BIT(2) + +/* EASC flush poll register */ +#define X_VC_EASC_FLUSH_POLL 0x161 +#define VC_EASC_FLUSH_POLL 0x308 +#define VC_EASC_FLUSH_POLL_BLOCK_ID PPC_BITMASK(0,3) +#define VC_EASC_FLUSH_POLL_OFFSET PPC_BITMASK(4,31) /* 28-bit */ +#define VC_EASC_FLUSH_POLL_BLOCK_ID_MASK PPC_BITMASK(32,35) +#define VC_EASC_FLUSH_POLL_OFFSET_MASK PPC_BITMASK(36,63) /* 28-bit */ + +/* + * VC2 + */ + +/* ENDC flush control register */ +#define X_VC_ENDC_FLUSH_CTRL 0x180 +#define VC_ENDC_FLUSH_CTRL 0x400 +#define VC_ENDC_FLUSH_CTRL_POLL_VALID PPC_BIT(0) +#define VC_ENDC_FLUSH_CTRL_WANT_CACHE_DISABLE PPC_BIT(2) +#define VC_ENDC_FLUSH_CTRL_WANT_INVALIDATE PPC_BIT(3) +#define VC_ENDC_FLUSH_CTRL_INJECT_INVALIDATE PPC_BIT(7) + +/* ENDC flush poll register */ +#define X_VC_ENDC_FLUSH_POLL 0x181 +#define VC_ENDC_FLUSH_POLL 0x408 +#define VC_ENDC_FLUSH_POLL_BLOCK_ID PPC_BITMASK(4,7) +#define VC_ENDC_FLUSH_POLL_OFFSET PPC_BITMASK(8,31) /* 24-bit */ +#define VC_ENDC_FLUSH_POLL_BLOCK_ID_MASK PPC_BITMASK(36,39) +#define VC_ENDC_FLUSH_POLL_OFFSET_MASK PPC_BITMASK(40,63) /* 24-bit */ + +/* ENDC Sync done */ +#define X_VC_ENDC_SYNC_DONE 0x184 +#define VC_ENDC_SYNC_DONE 0x420 +#define VC_ENDC_SYNC_POLL_DONE PPC_BITMASK(0,6) +#define VC_ENDC_SYNC_QUEUE_IPI PPC_BIT(0) +#define VC_ENDC_SYNC_QUEUE_HWD PPC_BIT(1) +#define VC_ENDC_SYNC_QUEUE_NXC PPC_BIT(2) +#define VC_ENDC_SYNC_QUEUE_INT PPC_BIT(3) +#define VC_ENDC_SYNC_QUEUE_OS PPC_BIT(4) +#define VC_ENDC_SYNC_QUEUE_POOL PPC_BIT(5) +#define VC_ENDC_SYNC_QUEUE_HARD PPC_BIT(6) +#define VC_QUEUE_COUNT 7 + +/* ENDC cache watch specification 0 */ +#define X_VC_ENDC_WATCH0_SPEC 0x1A0 +#define VC_ENDC_WATCH0_SPEC 0x500 +#define VC_ENDC_WATCH_CONFLICT PPC_BIT(0) +#define VC_ENDC_WATCH_FULL PPC_BIT(8) +#define VC_ENDC_WATCH_BLOCK_ID PPC_BITMASK(28, 31) +#define VC_ENDC_WATCH_INDEX PPC_BITMASK(40, 63) + +/* ENDC cache watch data 0 */ +#define X_VC_ENDC_WATCH0_DATA0 0x1A4 + +#define VC_ENDC_WATCH0_DATA0 0x520 + +/* + * PC LSB1 + */ + +/* VSD table address register */ +#define X_PC_VSD_TABLE_ADDR 0x200 +#define PC_VSD_TABLE_ADDR 0x000 +#define PC_VSD_TABLE_AUTOINC PPC_BIT(0) +#define PC_VSD_TABLE_SELECT PPC_BITMASK(12,15) +#define PC_VSD_TABLE_ADDRESS PPC_BITMASK(28,31) + +/* VSD table data register */ +#define X_PC_VSD_TABLE_DATA 0x201 +#define PC_VSD_TABLE_DATA 0x008 + +/* AT indirect kill register */ +#define X_PC_AT_KILL 0x202 +#define PC_AT_KILL 0x010 +#define PC_AT_KILL_VALID PPC_BIT(0) +#define PC_AT_KILL_VSD_TYPE PPC_BITMASK(24,27) +/* Only NVP, NVG, NVC */ +#define PC_AT_KILL_BLOCK_ID PPC_BITMASK(28,31) +#define PC_AT_KILL_OFFSET PPC_BITMASK(48,60) + +/* AT indirect kill mask register */ +#define X_PC_AT_KILL_MASK 0x203 +#define PC_AT_KILL_MASK 0x018 +#define PC_AT_KILL_MASK_VSD_TYPE PPC_BITMASK(24,27) +#define PC_AT_KILL_MASK_BLOCK_ID PPC_BITMASK(28,31) +#define PC_AT_KILL_MASK_OFFSET PPC_BITMASK(48,60) + +/* Error1 configuration register 0 */ +#define X_PC_ERR1_CFG0 0x2C8 +#define PC_ERR1_CFG0 0x640 + +/* Error1 configuration register 1 */ +#define X_PC_ERR1_CFG1 0x2C9 +#define PC_ERR1_CFG1 0x648 +#define PC_ERR1_CFG1_INTERRUPT_INVALID_PRIO PPC_BIT(3) +/* + * PC LSB2 + */ + +/* NxC Cache flush control */ +#define X_PC_NXC_FLUSH_CTRL 0x280 +#define PC_NXC_FLUSH_CTRL 0x400 +#define PC_NXC_FLUSH_CTRL_POLL_VALID PPC_BIT(0) +#define PC_NXC_FLUSH_CTRL_WANT_CACHE_DISABLE PPC_BIT(2) +#define PC_NXC_FLUSH_CTRL_WANT_INVALIDATE PPC_BIT(3) +#define PC_NXC_FLUSH_CTRL_INJECT_INVALIDATE PPC_BIT(7) + +/* NxC Cache flush poll */ +#define X_PC_NXC_FLUSH_POLL 0x281 +#define PC_NXC_FLUSH_POLL 0x408 +#define PC_NXC_FLUSH_POLL_NXC_TYPE PPC_BITMASK(2,3) +#define PC_NXC_FLUSH_POLL_NXC_TYPE_NVP 0 +#define PC_NXC_FLUSH_POLL_NXC_TYPE_NVG 2 +#define PC_NXC_FLUSH_POLL_NXC_TYPE_NVC 3 +#define PC_NXC_FLUSH_POLL_BLOCK_ID PPC_BITMASK(4,7) +#define PC_NXC_FLUSH_POLL_OFFSET PPC_BITMASK(8,31) /* 24-bit */ +#define PC_NXC_FLUSH_POLL_NXC_TYPE_MASK PPC_BITMASK(34,35) /* 0: Ignore */ +#define PC_NXC_FLUSH_POLL_BLOCK_ID_MASK PPC_BITMASK(36,39) +#define PC_NXC_FLUSH_POLL_OFFSET_MASK PPC_BITMASK(40,63) /* 24-bit */ + +/* NxC Cache Watch 0 Specification */ +#define X_PC_NXC_WATCH0_SPEC 0x2A0 +#define PC_NXC_WATCH0_SPEC 0x500 +#define PC_NXC_WATCH_CONFLICT PPC_BIT(0) +#define PC_NXC_WATCH_FULL PPC_BIT(8) +#define PC_NXC_WATCH_NXC_TYPE PPC_BITMASK(26, 27) +#define PC_NXC_WATCH_NXC_NVP 0 +#define PC_NXC_WATCH_NXC_NVG 2 +#define PC_NXC_WATCH_NXC_NVC 3 +#define PC_NXC_WATCH_BLOCK_ID PPC_BITMASK(28, 31) +#define PC_NXC_WATCH_INDEX PPC_BITMASK(40, 63) + +/* NxC Cache Watch 0 Data */ +#define X_PC_NXC_WATCH0_DATA0 0x2A4 + +#define PC_NXC_WATCH0_DATA0 0x520 + +/* + * TCTXT Registers + */ + +/* Physical Thread Enable0 register */ +#define X_TCTXT_EN0 0x300 +#define TCTXT_EN0 0x000 + +/* Physical Thread Enable0 Set register */ +#define X_TCTXT_EN0_SET 0x302 +#define TCTXT_EN0_SET 0x010 + +/* Physical Thread Enable0 Reset register */ +#define X_TCTXT_EN0_RESET 0x303 +#define TCTXT_EN0_RESET 0x018 + +/* Physical Thread Enable1 register */ +#define X_TCTXT_EN1 0x304 +#define TCTXT_EN1 0x020 + +/* Physical Thread Enable1 Set register */ +#define X_TCTXT_EN1_SET 0x306 +#define TCTXT_EN1_SET 0x030 + +/* Physical Thread Enable1 Reset register */ +#define X_TCTXT_EN1_RESET 0x307 +#define TCTXT_EN1_RESET 0x038 + +/* TCTXT Config register */ +#define X_TCTXT_CFG 0x328 +#define TCTXT_CFG 0x140 +#define TCTXT_CFG_FUSE_CORE_EN PPC_BIT(0) +#define TCTXT_CFG_PHYP_CORE_MODE PPC_BIT(1) /* O:Linux 1:pHyp */ +#define TCTXT_CFG_GEN1_HYP_TARGET_DIS PPC_BIT(4) +#define TCTXT_CFG_GEN1_OS_ST_ACK PPC_BIT(5) +#define TCTXT_CFG_GEN1_OGEN_FINE PPC_BIT(6) +#define TCTXT_CFG_INT_MSGSND_DIS PPC_BIT(17) +#define TCTXT_CFG_HOSTBOOT_MODE PPC_BIT(20) +#define TCTXT_CFG_COMPLEX_STORE_DIS PPC_BITMASK(25, 27) + +/* + * VSD Tables + */ +#define VST_ESB 0 +#define VST_EAS 1 /* No used by PC */ +#define VST_END 2 +#define VST_NVP 3 +#define VST_NVG 4 +#define VST_NVC 5 +#define VST_IC 6 /* No used by PC */ +#define VST_SYNC 7 +#define VST_ERQ 8 /* No used by PC */ + +/* Bits in a VSD entry. + * + * Note: the address is naturally aligned, we don't use a PPC_BITMASK, + * but just a mask to apply to the address before OR'ing it in. + * + * Note: VSD_FIRMWARE is a SW bit ! It hijacks an unused bit in the + * VSD and is only meant to be used in indirect mode ! + */ +#define VSD_MODE PPC_BITMASK(0,1) +#define VSD_MODE_SHARED 1 +#define VSD_MODE_EXCLUSIVE 2 +#define VSD_MODE_FORWARD 3 +#define VSD_FIRMWARE PPC_BIT(2) /* Read warning */ +#define VSD_FIRMWARE2 PPC_BIT(3) /* unused */ +#define VSD_RESERVED PPC_BITMASK(4,7) /* P10 reserved */ +#define VSD_ADDRESS_MASK 0x00fffffffffff000ull +#define VSD_MIGRATION_REG PPC_BITMASK(52,55) +#define VSD_INDIRECT PPC_BIT(56) +#define VSD_TSIZE PPC_BITMASK(59,63) + +/* EAS + * + * One per interrupt source. Targets that interrupt to a given END + * and provides the corresponding logical interrupt number (END data) + * + * We also map this structure to the escalation descriptor inside + * an END, though in that case the valid and masked bits are not used. + */ +struct xive_eas { + beint64_t w; +#define EAS_VALID PPC_BIT(0) +#define EAS_END_BLOCK PPC_BITMASK(4,7) /* Destination END block# */ +#define EAS_END_INDEX PPC_BITMASK(8,31) /* Destination END index */ +#define EAS_MASKED PPC_BIT(32) /* Masked */ +#define EAS_END_DATA PPC_BITMASK(33,63) /* Data written to the EQ */ +}; + +/* EQ */ +struct xive_end { + beint32_t w0; +#define END_W0_VALID PPC_BIT32(0) /* "v" bit */ +#define END_W0_ENQUEUE PPC_BIT32(5) /* "q" bit */ +#define END_W0_UCOND_NOTIFY PPC_BIT32(6) /* "n" bit */ +#define END_W0_SILENT_ESCALATE PPC_BIT32(7) /* "s" bit */ +#define END_W0_BACKLOG PPC_BIT32(8) /* "b" bit */ +#define END_W0_UNCOND_ESCALATE PPC_BIT32(10) /* "u" bit */ +#define END_W0_ESCALATE_CTL PPC_BIT32(11) /* "e" bit */ +#define END_W0_ESCALATE_END PPC_BIT32(13) /* "N" bit */ +#define END_W0_FIRMWARE1 PPC_BIT32(16) /* Owned by FW */ +#define END_W0_FIRMWARE2 PPC_BIT32(17) /* Owned by FW */ + beint32_t w1; +#define END_W1_ES PPC_BITMASK32(0,3) +#define END_W1_ESn PPC_BITMASK32(0,1) +#define END_W1_ESn_P PPC_BIT32(0) +#define END_W1_ESn_Q PPC_BIT32(1) +#define END_W1_ESe PPC_BITMASK32(2,3) +#define END_W1_ESe_P PPC_BIT32(2) +#define END_W1_ESe_Q PPC_BIT32(3) +#define END_W1_GEN_FLIPPED PPC_BIT32(8) +#define END_W1_GENERATION PPC_BIT32(9) +#define END_W1_PAGE_OFF PPC_BITMASK32(10,31) + beint32_t w2; +#define END_W2_RESERVED PPC_BITMASK32(4,7) +#define END_W2_EQ_ADDR_HI PPC_BITMASK32(8,31) + beint32_t w3; +#define END_W3_EQ_ADDR_LO PPC_BITMASK32(0,24) +#define END_W3_QSIZE PPC_BITMASK32(28,31) + beint32_t w4; +#define END_W4_END_BLOCK PPC_BITMASK32(4,7) /* N:1 */ +#define END_W4_ESC_END_INDEX PPC_BITMASK32(8,31) /* N:1 */ +#define END_W4_ESB_BLOCK PPC_BITMASK32(0,3) /* N:0 */ +#define END_W4_ESC_ESB_INDEX PPC_BITMASK32(4,31) /* N:0 */ + beint32_t w5; +#define END_W5_ESC_END_DATA PPC_BITMASK32(1,31) + beint32_t w6; +#define END_W6_FORMAT_BIT PPC_BIT32(0) +#define END_W6_VP_BLOCK PPC_BITMASK32(4,7) +#define END_W6_VP_OFFSET PPC_BITMASK32(8,31) +#define END_W6_VP_OFFSET_GEN1 PPC_BITMASK32(13,31) + beint32_t w7; +#define END_W7_TOPO PPC_BITMASK32(0,3) /* Owned by HW */ +#define END_W7_F0_PRIORITY PPC_BITMASK32(8,15) +#define END_W7_F1_LOG_SERVER_ID PPC_BITMASK32(4,31) +}; +#define xive_end_is_firmware1(end) \ + xive_get_field32(END_W0_FIRMWARE1, (end)->w0) + +/* Notification Virtual Processor (NVP) */ +struct xive_nvp { + beint32_t w0; +#define NVP_W0_VALID PPC_BIT32(0) +#define NVP_W0_HW PPC_BIT32(7) +#define NVP_W0_VPRIV PPC_BITMASK32(14,15) +#define NVP_W0_ESC_END PPC_BIT32(25) /* 'N' bit 0:ESB 1:END */ + beint32_t w1; + beint32_t w2; +#define NVP_W2_CPPR PPC_BITMASK32(0, 7) +#define NVP_W2_IPB PPC_BITMASK32(8, 15) +#define NVP_W2_LSMFB PPC_BITMASK32(16, 23) + beint32_t w3; + beint32_t w4; +#define NVP_W4_ESC_ESB_BLOCK PPC_BITMASK32(0, 3) /* N:0 */ +#define NVP_W4_ESC_ESB_INDEX PPC_BITMASK32(4, 31) /* N:0 */ +#define NVP_W4_ESC_END_BLOCK PPC_BITMASK32(4, 7) /* N:1 */ +#define NVP_W4_ESC_END_INDEX PPC_BITMASK32(8, 31) /* N:1 */ + beint32_t w5; +#define NVP_W5_PSIZE PPC_BITMASK32(0, 1) +#define NVP_W5_VP_END_BLOCK PPC_BITMASK32(4, 7) +#define NVP_W5_VP_END_INDEX PPC_BITMASK32(8, 31) + beint32_t w6; + beint32_t w7; +}; + +/* Notification Virtual Group or Crowd (NVG/NVC) */ +struct xive_nvgc { + beint32_t w0; +#define NVGC_W0_VALID PPC_BIT32(0) + beint32_t w1; + beint32_t w2; + beint32_t w3; + beint32_t w4; + beint32_t w5; + beint32_t w6; + beint32_t w7; +}; + +/* + * Thread Interrupt Management Area + * + * In Gen1 mode (P9 compat mode) word 2 is the same. However in Gen2 + * mode (P10), the CAM line is slightly different as the VP space was + * increased. + */ +#define TM10_QW0W2_VU PPC_BIT32(0) +#define TM10_QW0W2_LOGIC_SERV PPC_BITMASK32(4, 31) +#define TM10_QW1W2_VO PPC_BIT32(0) +#define TM10_QW1W2_HO PPC_BIT32(1) +#define TM10_QW1W2_NO PPC_BIT32(2) +#define TM10_QW1W2_OS_CAM PPC_BITMASK32(4, 31) +#define TM10_QW2W2_VP PPC_BIT32(0) +#define TM10_QW2W2_HP PPC_BIT32(1) +#define TM10_QW2W2_NP PPC_BIT32(2) +#define TM10_QW2W2_POOL_CAM PPC_BITMASK32(4, 31) +#define TM10_QW3W2_VT PPC_BIT32(0) +#define TM10_QW3W2_HT PPC_BIT32(1) +#define TM10_QW3W2_NT PPC_BIT32(2) +#define TM10_QW3W2_LP PPC_BIT32(6) +#define TM10_QW3W2_LE PPC_BIT32(7) + +#endif /* XIVE2_REGS_H */ diff --git a/roms/skiboot/include/xscom-p10-regs.h b/roms/skiboot/include/xscom-p10-regs.h new file mode 100644 index 000000000..6045152d2 --- /dev/null +++ b/roms/skiboot/include/xscom-p10-regs.h @@ -0,0 +1,56 @@ +#ifndef __XSCOM_P10_REGS_H__ +#define __XSCOM_P10_REGS_H__ + +/* Core FIR (Fault Isolation Register) */ +#define P10_CORE_FIR 0x440 + +#define P10_CORE_FIRMASK_OR 0x445 + +/* Core WOF (Whose On First) */ +#define P10_CORE_WOF 0x448 + +#define P10_MALFUNC_ALERT 0x00090022 + +#define P10_NX_STATUS_REG 0x02011040 /* NX status register */ +#define P10_NX_DMA_ENGINE_FIR 0x02011100 /* DMA & Engine FIR Data Register */ +#define P10_NX_PBI_FIR 0x02011080 /* PowerBus Interface FIR Register */ + +#define P10_EC_CORE_THREAD_STATE 0x412 /* XXX P10 is this right? */ +#define P10_THREAD_STOPPED(t) PPC_BIT(56 + (t)) + +#define P10_EC_THREAD_INFO 0x413 +#define P10_THREAD_ACTIVE(t) PPC_BIT(t) + +#define P10_EC_RAS_STATUS 0x454 +#define P10_THREAD_MAINT(t) PPC_BIT(0 + 8*(t)) +#define P10_THREAD_QUIESCED(t) PPC_BIT(1 + 8*(t)) +#define P10_THREAD_ICT_EMPTY(t) PPC_BIT(2 + 8*(t)) + +#define P10_EC_DIRECT_CONTROLS 0x449 +#define P10_THREAD_STOP(t) PPC_BIT(7 + 8*(t)) +#define P10_THREAD_START(t) PPC_BIT(6 + 8*(t)) +#define P10_THREAD_SRESET(t) PPC_BIT(4 + 8*(t)) +#define P10_THREAD_CLEAR_MAINT(t) PPC_BIT(3 + 8*(t)) +#define P10_THREAD_PWR(t) PPC_BIT(32 + 8*(t)) + +#define P10_QME_FIR 0x000 + +#define P10_QME_SPWU_HYP 0x83c +#define P10_SPWU_REQ PPC_BIT(0) +#define P10_SPWU_DONE PPC_BIT(4) + +#define P10_QME_SSH_HYP 0x82c +#define P10_SSH_CORE_GATED PPC_BIT(0) +#define P10_SSH_SPWU_DONE PPC_BIT(1) + +#define P10_NCU_STATUS_REG 0x64f +#define P10_NCU_SPEC_BAR 0x650 +#define P10_NCU_SPEC_BAR_ENABLE PPC_BIT(0) +#define P10_NCU_SPEC_BAR_256K PPC_BIT(1) +#define P10_NCU_SPEC_BAR_ADDRMSK 0x000fffffffffc000ull /* 16k aligned */ + +#define P10_NCU_DARN_BAR 0x651 +#define P10_NCU_DARN_BAR_EN PPC_BIT(0) +#define P10_NCU_DARN_BAR_ADDRMSK 0x000ffffffffff000ull /* 4k aligned */ + +#endif /* __XSCOM_P10_REGS_H__ */ diff --git a/roms/skiboot/include/xscom-p8-regs.h b/roms/skiboot/include/xscom-p8-regs.h new file mode 100644 index 000000000..2192b6e71 --- /dev/null +++ b/roms/skiboot/include/xscom-p8-regs.h @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Copyright 2013-2019 IBM Corp. + */ + +#ifndef __XSCOM_P8_REGS_H__ +#define __XSCOM_P8_REGS_H__ + +/* Core FIR (Fault Isolation Register) */ +#define P8_CORE_FIR 0x10013100 + +/* Direct controls */ +#define P8_EX_TCTL_DIRECT_CONTROLS(t) (0x10013000 + (t) * 0x10) +#define P8_DIRECT_CTL_STOP PPC_BIT(63) +#define P8_DIRECT_CTL_PRENAP PPC_BIT(47) +#define P8_DIRECT_CTL_SRESET PPC_BIT(60) + +/* pMisc Receive Malfunction Alert Register */ +#define P8_MALFUNC_ALERT 0x02020011 + +#define P8_NX_STATUS_REG 0x02013040 /* NX status register */ +#define P8_NX_DMA_ENGINE_FIR 0x02013100 /* DMA & Engine FIR Data Register */ +#define P8_NX_PBI_FIR 0x02013080 /* PowerBus Interface FIR Register */ + +/* + * Bit 54 from NX status register is set to 1 when HMI interrupt is triggered + * due to NX checksop. + */ +#define NX_HMI_ACTIVE PPC_BIT(54) + +/* Per core power mgt registers */ +#define PM_OHA_MODE_REG 0x1002000D +#define L2_FIR_ACTION1 0x10012807 + +/* EX slave per-core power mgt slave regisers */ +#define EX_PM_GP0 0x0100 +#define EX_PM_GP1 0x0103 +#define EX_PM_CLEAR_GP1 0x0104 /* AND SCOM */ +#define EX_PM_SET_GP1 0x0105 /* OR SCOM */ +#define EX_PM_SPECIAL_WAKEUP_FSP 0x010B +#define EX_PM_SPECIAL_WAKEUP_OCC 0x010C +#define EX_PM_SPECIAL_WAKEUP_PHYP 0x010D +#define EX_PM_IDLE_STATE_HISTORY_PHYP 0x0110 +#define EX_PM_IDLE_STATE_HISTORY_FSP 0x0111 +#define EX_PM_IDLE_STATE_HISTORY_OCC 0x0112 +#define EX_PM_IDLE_STATE_HISTORY_PERF 0x0113 +#define EX_PM_CORE_PFET_VRET 0x0130 +#define EX_PM_CORE_ECO_VRET 0x0150 +#define EX_PM_PPMSR 0x0153 +#define EX_PM_PPMCR 0x0159 + +/* Power mgt bits in GP0 */ +#define EX_PM_GP0_SPECIAL_WAKEUP_DONE PPC_BIT(31) + +/* Power mgt settings in GP1 */ +#define EX_PM_SETUP_GP1_FAST_SLEEP 0xD800000000000000ULL +#define EX_PM_SETUP_GP1_DEEP_SLEEP 0x2400000000000000ULL +#define EX_PM_SETUP_GP1_FAST_SLEEP_DEEP_WINKLE 0xC400000000000000ULL +#define EX_PM_GP1_SLEEP_WINKLE_MASK 0xFC00000000000000ULL +#define EX_PM_SETUP_GP1_PM_SPR_OVERRIDE_EN 0x0010000000000000ULL +#define EX_PM_SETUP_GP1_DPLL_FREQ_OVERRIDE_EN 0x0020000000000000ULL + +/* Fields in history regs */ +#define EX_PM_IDLE_ST_HIST_PM_STATE_MASK PPC_BITMASK(0, 2) +#define EX_PM_IDLE_ST_HIST_PM_STATE_LSH PPC_BITLSHIFT(2) + +#endif /* __XSCOM_P8_REGS_H__ */ diff --git a/roms/skiboot/include/xscom-p9-regs.h b/roms/skiboot/include/xscom-p9-regs.h new file mode 100644 index 000000000..a2a17d0fc --- /dev/null +++ b/roms/skiboot/include/xscom-p9-regs.h @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Copyright 2016-2019 IBM Corp. + */ + +#ifndef __XSCOM_P9_REGS_H__ +#define __XSCOM_P9_REGS_H__ + +/* Core FIR (Fault Isolation Register) */ +#define P9_CORE_FIR 0x20010A40 + +/* Core WOF (Whose On First) */ +#define P9_CORE_WOF 0x20010A48 + +/* pMisc Receive Malfunction Alert Register */ +#define P9_MALFUNC_ALERT 0x00090022 + +#define P9_NX_STATUS_REG 0x02011040 /* NX status register */ +#define P9_NX_DMA_ENGINE_FIR 0x02011100 /* DMA & Engine FIR Data Register */ +#define P9_NX_PBI_FIR 0x02011080 /* PowerBus Interface FIR Register */ + +/* + * Bit 54 from NX status register is set to 1 when HMI interrupt is triggered + * due to NX checksop. + */ +#define NX_HMI_ACTIVE PPC_BIT(54) + +/* Direct controls */ +#define P9_EC_DIRECT_CONTROLS 0x10a9c +#define P9_THREAD_STOP(t) PPC_BIT(7 + 8*(t)) +#define P9_THREAD_CONT(t) PPC_BIT(6 + 8*(t)) +#define P9_THREAD_SRESET(t) PPC_BIT(4 + 8*(t)) +#define P9_THREAD_CLEAR_MAINT(t) PPC_BIT(3 + 8*(t)) +#define P9_THREAD_PWR(t) PPC_BIT(32 + 8*(t)) + +#define P9_RAS_STATUS 0x10a02 +#define P9_THREAD_QUIESCED(t) PPC_BITMASK(0 + 8*(t), 3 + 8*(t)) + +#define P9_CORE_THREAD_STATE 0x10ab3 +#define P9_THREAD_INFO 0x10a9b + +/* EC_PPM_SPECIAL_WKUP_HYP */ +#define P9_SPWKUP_SET PPC_BIT(0) + +#define P9_EC_PPM_SSHHYP 0x0114 +#define P9_CORE_GATED PPC_BIT(0) +#define P9_SPECIAL_WKUP_DONE PPC_BIT(1) + +/* EX (core pair) registers, use XSCOM_ADDR_P9_EX to access */ +#define P9X_EX_NCU_STATUS_REG 0x1100f +#define P9X_EX_NCU_SPEC_BAR 0x11010 +#define P9X_EX_NCU_SPEC_BAR_ENABLE PPC_BIT(0) +#define P9X_EX_NCU_SPEC_BAR_256K PPC_BIT(1) +#define P9X_EX_NCU_SPEC_BAR_ADDRMSK 0x0fffffffffffc000ull /* naturally aligned */ + +#define P9X_NX_MMIO_BAR 0x201108d +#define P9X_NX_MMIO_BAR_EN PPC_BIT(52) +#define P9X_NX_MMIO_OFFSET 0x00060302031d0000ull + +#define P9X_NX_RNG_CFG 0x20110E0 +#define P9X_NX_RNG_CFG_EN PPC_BIT(63) + +#define P9X_EX_NCU_DARN_BAR 0x11011 +#define P9X_EX_NCU_DARN_BAR_EN PPC_BIT(0) + +#define P9_GPIO_DATA_OUT 0x00000000000B0051ull +#define P9_GPIO_DATA_OUT_ENABLE 0x00000000000B0054ull +#define P9_GPIO_INTERRUPT_STATUS 0x00000000000B0057ull +#define P9_GPIO_INTERRUPT_ENABLE 0x00000000000B005Dull +#define P9_GPIO_INTERRUPT_CONDITION 0x00000000000B005Eull + +/* xscom address for SCOM Control and data Register */ +/* bits 54:60 of SCOM SPRC register is used for core specific SPR selection. */ +#define P9_SCOM_SPRC 0x20010A80 +#define P9_SCOMC_SPR_SELECT PPC_BITMASK(54, 60) +#define P9_SCOMC_TFMR_T0 0x8 /* 0b0001000 TFMR */ + +#define P9_SCOM_SPRD 0x20010A81 + +#define PB_CENT_HP_MODE_CURR 0x5011c0c +#define PB_CFG_CHG_RATE_GP_MASTER PPC_BIT(2) +#define PB_CFG_PUMP_MODE PPC_BIT(54) + +/* Power 9 EC slave per-core power mgt slave registers */ +#define EC_PPM_SPECIAL_WKUP_OTR 0x010A +#define EC_PPM_SPECIAL_WKUP_FSP 0x010B +#define EC_PPM_SPECIAL_WKUP_OCC 0x010C +#define EC_PPM_SPECIAL_WKUP_HYP 0x010D + +#define OB_BASE(ob) (((ob) + 9) << 24) +#define OB_CPLT_CONF1(ob) (OB_BASE(ob) + 0x9) +#define OB_CPLT_CONF1_NV_IOVALID(brk) PPC_BIT(6 + (brk)) +#define OB_INDIRECT(ob) ((OB_BASE(ob) + 0x10c3f) | PPC_BIT(0)) + +/* PPE SRAM: Indirect address/data port */ +#define OB_PPE_CSAR(ob) (OB_BASE(ob) + 0x1104d) +#define OB_PPE_CSAR_SRAM_ADDR PPC_BITMASK(16, 28) +#define OB_PPE_CSDR(ob) (OB_BASE(ob) + 0x1104e) + +/* PPE SRAM: Indirect registers */ +#define OB_PPE_SALT_CMD 0x1fe6 +#define OB_PPE_SALT_CMD_READY PPC_BIT(0) +#define OB_PPE_SALT_CMD_RW PPC_BIT(1) +#define OB_PPE_SALT_CMD_ERR PPC_BIT(2) +#define OB_PPE_SALT_CMD_LINKNUM PPC_BITMASK(15, 18) +#define OB_PPE_SALT_CMD_REG PPC_BITMASK(19, 31) +#define OB_PPE_SALT_CMD_DATA PPC_BITMASK(32, 63) + +#endif /* __XSCOM_P9_REGS_H__ */ diff --git a/roms/skiboot/include/xscom.h b/roms/skiboot/include/xscom.h new file mode 100644 index 000000000..a6bb7e400 --- /dev/null +++ b/roms/skiboot/include/xscom.h @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __XSCOM_H +#define __XSCOM_H + +#include <stdint.h> +#include <processor.h> +#include <cpu.h> + +/* + * SCOM "partID" definitions: + * + * All Ids are 32-bits long, top nibble is reserved for the + * 'type' field: + * 0x0 = Processor Chip + * 0x8 = Memory Buffer (Centaur) Chip + * 0x4 = EX/Core Chiplet + * + * Processor Chip = Logical Fabric Id = PIR>>7 + * 0b0000.0000.0000.0000.0000.0000.00NN.NCCC + * N=Node, C=Chip + * Centaur Chip = Associated Processor Chip with memory channel + * appended and flag set + * 0b1000.0000.0000.0000.0000.00NN.NCCC.MMMM + * N=Node, C=Chip, M=Memory Channel + * Processor EX/Core chiplet = PIR >> 3 with flag set. + * On P8: + * 0b0100.0000.0000.0000.0000.00NN.NCCC.PPPP + * On P9: + * 0b0100.0000.0000.0000.0000.0NNN.CCCP.PPPP + * N=Node, C=Chip, P=Processor core + */ + +/* + * SCOM Address definition extracted from HWPs for documentation + * purposes + * + * "Normal" (legacy) format + * + * 111111 11112222 22222233 33333333 44444444 44555555 55556666 + * 01234567 89012345 67890123 45678901 23456789 01234567 89012345 67890123 + * -------- -------- -------- -------- -------- -------- -------- -------- + * 00000000 00000000 00000000 00000000 0MCCCCCC ????PPPP 00LLLLLL LLLLLLLL + * || | | + * || | `-> Local Address* + * || | + * || `-> Port + * || + * |`-> Chiplet ID** + * | + * `-> Multicast bit + * + * * Local address is composed of "00" + 4-bit ring + 10-bit ID + * The 10-bit ID is usually 4-bit sat_id and 6-bit reg_id + * + * ** Chiplet ID turns into multicast operation type and group number + * if the multicast bit is set + * + * "Indirect" format + * + * + * 111111 11112222 22222233 33333333 44444444 44555555 55556666 + * 01234567 89012345 67890123 45678901 23456789 01234567 89012345 67890123 + * -------- -------- -------- -------- -------- -------- -------- -------- + * 10000000 0000IIII IIIIIGGG GGGLLLLL 0MCCCCCC ????PPPP 00LLLLLL LLLLLLLL + * | | | || | | + * | | | || | `-> Local Address* + * | | | || | + * | | | || `-> Port + * | | | || + * | | | |`-> Chiplet ID** + * | | | | + * | | | `-> Multicast bit + * | | | + * | | `-> Lane ID + * | | + * | `-> RX or TX Group ID + * | + * `-> Indirect Register Address + * + * * Local address is composed of "00" + 4-bit ring + 4-bit sat_id + "111111" + * + * ** Chiplet ID turns into multicast operation type and group number + * if the multicast bit is set + */ + +/* + * Generate a local address from a given ring/satellite/offset + * combination: + * + * Ring Satellite offset + * +---------+---------+-------------+ + * | 4 | 4 | 6 | + * +---------+---------+-------------+ + */ +#define XSCOM_SAT(_r, _s, _o) \ + (((_r) << 10) | ((_s) << 6) | (_o)) + +/* + * Additional useful definitions for P8 + */ +#define P8_EX_PCB_SLAVE_BASE 0x100F0000 + +#define XSCOM_ADDR_P8_EX_SLAVE(core, offset) \ + (P8_EX_PCB_SLAVE_BASE | (((core) & 0xF) << 24) | ((offset) & 0xFFFF)) + +#define XSCOM_ADDR_P8_EX(core, addr) \ + ((((core) & 0xF) << 24) | (addr)) + +/* + * Additional useful definitions for P9 + * + * Note: In all of these, the core numbering is the + * *normal* (small) core number. + */ + +/* + * An EQ is a quad. The Pervasive spec also uses the term "EP" + * to refer to an EQ and it's two child EX chiplets, but + * nothing else does + */ +#define XSCOM_ADDR_P9_EQ(core, addr) \ + (((((core) & 0x1c) + 0x40) << 22) | (addr)) +#define XSCOM_ADDR_P9_EQ_SLAVE(core, addr) \ + XSCOM_ADDR_P9_EQ(core, (addr) | 0xf0000) + +/* An EX is a pair of cores. They are accessed via their corresponding EQs + * with bit 0x400 indicating which of the 2 EX to address + */ +#define XSCOM_ADDR_P9_EX(core, addr) \ + (XSCOM_ADDR_P9_EQ(core, addr | (((core) & 2) << 9))) + +/* An EC is an individual core and has its own XSCOM addressing */ +#define XSCOM_ADDR_P9_EC(core, addr) \ + (((((core) & 0x1F) + 0x20) << 24) | (addr)) +#define XSCOM_ADDR_P9_EC_SLAVE(core, addr) \ + XSCOM_ADDR_P9_EC(core, (addr) | 0xf0000) + +/* + * Additional useful definitions for P10 + */ + +/* + * POWER10 pervasive structure + * Chip has 8 EQ chiplets (aka super-chiplets), and other nest chiplets. + * Each EQ contains 4 EX regions. + * Each EX contains an ECL2, L3, MMA. + * Each ECL2 contains an EC (core), L2, and NCU. + * + * Each EQ has a Quad Management Engine (QME), responsible for power management + * for the cores, among other things. + * + * POWER10 XSCOM address format: + * + * | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16-31| + * MC=0 |WR|MC|SLAVE ADDR |PIB MASTER |PORT NUMBER|LOCAL| + * MC=1 |WR|MC|MC TYPE |MC GROUP|PIB MASTER |PORT NUMBER|LOCAL| + * + * * Port is also known as PSCOM endpoint. + * + * WR is set by the xscom access functions (XSCOM_DATA_IND_READ bit) + * MC is always 0 (skiboot does not use multicast scoms). + * + * For unicast: + * EQ0-7 is addressed from 0x20 to 0x27 in the top 8 bits. + * L3 is on port 1 + * NCU is on port 1 + * ECL2 (core+L2) is on port 2 (XXX P10 scoms html doc suggests port 1?) + * QME is on port E. + * + * EQ chiplets (aka super chiplet) local address format: + * + * | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15| + * |C0|C1|C2|C3|RING ID |SAT ID |REGISTER ID | + * + * EX0-4 are selected with one-hot encoding (C0-3) + * + * QME per-core register access address format: + * | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15| + * |C0|C1|C2|C3| 1| 0| 0| 0|PER-CORE REGISTER ID | + * + * NCU - ring 6 (port 1) + * L3 - ring 3 (port 1) (XXX P10 scoms html doc suggests ring 6) + * L2 - ring 0 (port 2) (XXX P10 scoms html doc suggests ring 4) + * EC (PC unit) - rings 2-5 (port 2) + * + * Other chiplets: + * + * | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15| + * | 1|RING ID |SAT ID |REGISTER ID | + */ + +#define P10_CORE_EQ_CHIPLET(core) (0x20 + ((core) >> 2)) +#define P10_CORE_PROC(core) ((core) & 0x3) + +#define XSCOM_P10_EQ(chiplet) ((chiplet) << 24) + +#define XSCOM_P10_QME(chiplet) \ + (XSCOM_P10_EQ(chiplet) | (0xE << 16)) + +#define XSCOM_P10_QME_CORE(chiplet, proc) \ + (XSCOM_P10_QME(chiplet) | ((1 << (3 - proc)) << 12)) + +#define XSCOM_P10_EC(chiplet, proc) \ + (XSCOM_P10_EQ(chiplet) | (0x2 << 16) | ((1 << (3 - proc)) << 12)) + +#define XSCOM_P10_NCU(chiplet, proc) \ + (XSCOM_P10_EQ(chiplet) | (0x1 << 16) | ((1 << (3 - proc)) << 12)) + +#define XSCOM_ADDR_P10_EQ(core, addr) \ + (XSCOM_P10_EQ(P10_CORE_EQ_CHIPLET(core)) | (addr)) + +#define XSCOM_ADDR_P10_QME(core, addr) \ + (XSCOM_P10_QME(P10_CORE_EQ_CHIPLET(core)) | (addr)) + +#define XSCOM_ADDR_P10_QME_CORE(core, addr) \ + (XSCOM_P10_QME_CORE(P10_CORE_EQ_CHIPLET(core), P10_CORE_PROC(core)) | (addr)) + +#define XSCOM_ADDR_P10_EC(core, addr) \ + (XSCOM_P10_EC(P10_CORE_EQ_CHIPLET(core), P10_CORE_PROC(core)) | (addr)) + +#define XSCOM_ADDR_P10_NCU(core, addr) \ + (XSCOM_P10_NCU(P10_CORE_EQ_CHIPLET(core), P10_CORE_PROC(core)) | (addr)) + +/* Definitions relating to indirect XSCOMs shared with centaur */ +#define XSCOM_ADDR_IND_FLAG PPC_BIT(0) +#define XSCOM_ADDR_IND_ADDR PPC_BITMASK(12,31) +#define XSCOM_ADDR_IND_DATA PPC_BITMASK(48,63) + +#define XSCOM_DATA_IND_READ PPC_BIT(0) +#define XSCOM_DATA_IND_COMPLETE PPC_BIT(32) +#define XSCOM_DATA_IND_ERR PPC_BITMASK(33,35) +#define XSCOM_DATA_IND_DATA PPC_BITMASK(48,63) +#define XSCOM_DATA_IND_FORM1_DATA PPC_BITMASK(12,63) + +/* HB folks say: try 10 time for now */ +#define XSCOM_IND_MAX_RETRIES 10 + +/* Max number of retries when XSCOM remains busy */ +#define XSCOM_BUSY_MAX_RETRIES 3000 + +/* Max number of retries for xscom clearing recovery. */ +#define XSCOM_CLEAR_MAX_RETRIES 10 + +/* Retry count after which to reset XSCOM, if still busy */ +#define XSCOM_BUSY_RESET_THRESHOLD 1000 + +/* + * Error handling: + * + * Error codes TBD, 0 = success + */ + +/* Use only in select places where multiple SCOMs are time/latency sensitive */ +extern void _xscom_lock(void); +extern int _xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val, bool take_lock); +extern int _xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val, bool take_lock); +extern void _xscom_unlock(void); + + +/* Targeted SCOM access */ +static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) +{ + return _xscom_read(partid, pcb_addr, val, true); +} +static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) { + return _xscom_write(partid, pcb_addr, val, true); +} +extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask); + +/* This chip SCOM access */ +extern int xscom_readme(uint64_t pcb_addr, uint64_t *val); +extern int xscom_writeme(uint64_t pcb_addr, uint64_t val); +extern void xscom_init(void); + +/* Mark XSCOM lock as being in console path */ +extern void xscom_used_by_console(void); + +/* Returns true if XSCOM can be used. Typically this returns false if + * the current CPU holds the XSCOM lock (to avoid re-entrancy from error path). + */ +extern bool xscom_ok(void); + +extern int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id); +extern int64_t xscom_trigger_xstop(void); + + +struct scom_controller { + uint32_t part_id; + void *private; + int64_t (*read)(struct scom_controller *, uint32_t chip, uint64_t reg, uint64_t *val); + int64_t (*write)(struct scom_controller *, uint32_t chip, uint64_t reg, uint64_t val); + + struct list_node link; +}; + +int64_t scom_register(struct scom_controller *new); + +#endif /* __XSCOM_H */ |